Juploader 1.0 谷歌(chrome)浏览器中成功上传文件后返回信息异常
在项目中使用了Juploader 1.0无刷新上传文件的js组件,在IE8以上没有问题,代码如下:
- function InitialUploadDirectly(OnUploadFunc, buttonID, allowedExts) {
- $.jUploader({
- button: buttonID, // 这里设置按钮id
- eventType: 1, //触发类型
- addeventbutton: buttonID, // 要绑定事件的元素的id
- filenamed: buttonID + 'divFileName', //存放选择的文件路径的文本框的id
- checkMethod: function () { return checkForm(); },
- afterChoose: function (fileName) { afterUpload(fileName, buttonID); },
- allowedExtensions: allowedExts, // 设置允许上传的后缀,当然最好在服务器端也做验证
- // 开始上传事件
- onUpload: function (fileName) {
- var url = "**.ashx";
- if (OnUploadFunc != null) {
- url = OnUploadFunc();
- }
- $.jBox.tip("正在上传文件,请稍候!", "loading");
- return url;
- },
- // 上传完成事件
- onComplete: function (fileName, response) {
- // response是json对象,格式可以按自己的意愿来定义,例子为: { success: true, fileUrl:'' }
- console.log(response);
- if (response.Msg == "success") {
- AfterUploadCompleteSuccess(response.AddedFile.S_ID, fileName);
- }
- else if (response.Msg == "error") {
- jBox.closeTip();
- jBox.error("文件大小不能超过50M", "错误提示");
- }
- else {
- jBox.closeTip();
- jBox.error(response.Msg, "错误提示");
- }
- },
- // 系统信息显示(例如后缀名不合法)
- showMessage: function (message) {
- jBox.tip(message, 'error');
- },
- // 取消上传事件
- onCancel: function (fileName) {
- jBox.tip(fileName + ' 上传取消。', 'info');
- },
- // 自己定义文字
- messages: {
- upload: '添加附件...',
- emptyFile: "{file} 为空,请选择一个文件.",
- invalidExtension: "{file} 后缀名不合法. 只有 {extensions} 是允许的.",
- onLeave: "文件正在上传,如果你现在离开,上传将会被取消。"
- }
- });
- }
但是使用Chrome(我测试的版本为31)浏览器测试的时候,虽然服务器已经接收到上传的文件,并且返回了json格式的数据对象,但是前台脚本中始终得不到返回值,response始终为{“Msg”:”error”},查看Jquploader的源码,发现response是在complete事件中try catch 中异常情况中赋的值,下面代码中黄色标识的部分
- var complete = function () {
- try {
- options.uploading = false;
- $('#jUploader-file' + options.id).show();
- options.button.children('span').text(options.messages.upload);
- var iframe = $('#jUploaderIframe' + options.id).get(0);
- // when we remove iframe from dom
- // the request stops, but in IE load
- // event fires
- if (!iframe.parentNode) {
- return;
- }
- // fixing Opera 10.53
- if ((iframe.contentDocument &&
- iframe.contentDocument.body &&
- iframe.contentDocument.body.innerHTML == "false")
- || (iframe.contentWindow.document &&
- iframe.contentWindow.document.body &&
- iframe.contentWindow.document.body.innerHTML == "false")) {
- // In Opera event is fired second time
- // when body.innerHTML changed from false
- // to server response approx. after 1 sec
- // when we upload file with iframe
- return;
- }
- // iframe.contentWindow.document - for IE<7
- var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document;
- var response;
- log("innerHTML = " + doc.body.innerHTML);
- try {
- var json = doc.body.innerHTML.replace(/<pre>(.*)<\/pre>/g, '$1');
- response = eval("(" + json + ")");
- } catch (e) {
- response = { "Msg": "error" };
- //throw e;
- }
- console.log(response);
- // timeout added to fix busy state in FF3.6
- setTimeout(function () {
- $('#jUploaderForm' + options.id).remove();
- $('#jUploaderIframe' + options.id).remove();
- }, 10);
- options.onComplete(options.fileName, response);
- }
- catch (e) {
- setTimeout(function () {
- $('#jUploaderForm' + options.id).remove();
- $('#jUploaderIframe' + options.id).remove();
- }, 10);
- response = { "Msg": "error" };
- options.onComplete(options.fileName, response);
- }
- };
继续调试发现下面这段代码中
var json = doc.body.innerHTML.replace(/<pre>(.*)<\/pre>/g, '$1');的json始终为空,但是实际上后台是返回了值的。
继续查看源码,明白了Juploader的基本思想,是在页面中创建iframe,再在iframe中构建一个form,form的action指向上传文件的后台服务器地址,如下:
- $(document.body).append(createIframe()).append(createForm());
并且在iframe的onload事件中绑定自定义的complete方法,如下:
- var createIframe = function () {
- var id = 'jUploaderIframe' + options.id;
- var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>').bind('load', complete);
- return iframe;
- };
这样在iframe中的form加载完成后会执行iframe的onload事件(具体iframe的onload事件的用法,可自行百度,这里不多做解释了)。
但是在调试过程中却发现onload的事件总是先执行,也就是说complete方法在执行的时候form其实还没有加载完成,以下是控制台日志显示内容:
于是怀疑是因为代码顺序的问题造成的,再看一下具体的代码
createIframe方法中:
- var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>').bind('load', complete);
upload方法中:
- $(document.body).append(createIframe()).append(createForm());
于是调整代码在iframe append form 后,再bind iframe 的onload事件
createIframe方法中
- var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>')
去掉了bind load 的事件
而在upload方法中:
- var ifrm = createIframe();
- $(document.body).append(ifrm).append(createForm());
- ifrm.bind("load", complete);
这样修改之后,上传完成事件onComplete 的response参数就可以正常获取form 中action 页面的回传值了
Juploader 1.0 谷歌(chrome)浏览器中成功上传文件后返回信息异常的更多相关文章
- IE浏览器上传文件后返回结果会自动弹出下载框
服务器使用的是node,其它语言的后台没测试过. 在IE低版本浏览器下,当你上传一个文件后后台会返回一些数据,但是IE浏览器会弹出下载提示. 这个问题是之前处理的了,没有细究,今天有人问到这个问题,顺 ...
- nss_12 上传文件后返回jsonresult结果,IE中出现文件下载框
因为控制器返回的是JsonResult, 但是在IE8中一直返回文件下载的对话框. 转到谷歌浏览器倒没有问题. 网上找的方法, 要么是跟到一个新的成功页面, 要么是直接返回html, 觉得应该有更好的 ...
- 在asp.net 中怎样上传文件夹
以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传 ...
- Android应用开发中webview上传文件的几种思路
1. 常规方法,重写WebChromeClient 的 openFileChooser 方法 private class MyWebChromeClient extends WebChromeClie ...
- ASP.Net在web.config中设置上传文件的大小方法
修改Webcong文件:<system.web><httpRuntime maxRequestLength="40960" //即40MB,1KB=1024u ...
- tp中附件上传文件,表单提交
public function tianjia(){ $goods=D('Goods'); if(!empty($_POST)){ if($_FILES['f_goods_image']['error ...
- 定制FileField中的上传文件名称
FileField中的upload_to属性可以设定上传文件的存储目录和名称,它可以是个字符串,也可以是个callable,比如一个方法. 当upload_to的值设为一个方法时,就可以对上传文件的名 ...
- SpringMvc (注解)中的上传文件
第一步:导入commons-fileupload-1.3.1.jar 和commons-io-2.2.jar 架包 第二步:在applicationContext.xml中 配置 <bean i ...
- 【Azure 应用服务】PHP应用部署在App Service for Linux环境中,上传文件大于1MB时,遇见了413 Request Entity Too Large 错误的解决方法
问题描述 在PHP项目部署在App Service后,上传文件如果大于1MB就会遇见 413 Request Entity Too Large 的问题. 问题解决 目前这个问题,首先需要分析应用所在的 ...
随机推荐
- dyld_shared_cache_extract_dylibs failed
文章来源:https://www.jianshu.com/p/e276a784fbee s.png 数据线插上手机 Xcode->window 3.png 2.png 点击Unpai ...
- ShoppingCart类图
1,组合关系,实心的棱形画在整体上面,发现很多人把它画错了 2,1..*或*代表的意义说明: 完整格式为:最小数量..最大数量 约束:前者必须小于后者,如1..*表示1个或多个,不会包含1..0这种情 ...
- hibernate重要知识点总结
一.使用注解方式-----实体和表之间的映射 配置spring的applicationContext.xml文件: <bean id="sessionFactory" cla ...
- pip 更改国内镜像
2 pip 更改国内镜像 pip 默认不使用国内镜像,但是我们可以自己设置 -[pypi 镜像使用帮助] 临时使用 pip install -i https://pypi.tuna.tsinghua. ...
- Cocos Creator 资源加载(笔记)
cc.loader 加载资源动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下.resources 需要在 assets 文件夹中手工 ...
- 斐讯面试记录—TCP滑动窗口及拥塞控制
TCP协议作为一个可靠的面向流的传输协议,其可靠性是由流量控制和滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现. 一.滑动窗口协议 1. “窗口”对应的是一段可以被发送者发送的字节序 ...
- MTCNN试用
检测工作想借用MTCNN里的48-net,源码来自CongWeilin Git 下下来就能跑,真是良心 进入pepare_data准备好数据以后进入48-net,目录下有一个pythonLayer.p ...
- eclipse自定义快捷键(模板)
window->Preferences->Java->Editor->Templates https://blog.csdn.net/changqing5818/article ...
- mybatis 查询优化主子表查询之association和collection
很多开发人员之所以编写出低效的应用,有一大原因是并不理解怎样编写高效的SQL.以订单查询为例,我们经常需要查询某个用户的订单以及订单明细,并且以树形方式展现如下: 对于这种性质的功能,很多开发人员的做 ...
- 剑指offer(3)从尾到头打印链表
题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ t ...