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 的问题. 问题解决 目前这个问题,首先需要分析应用所在的 ...
随机推荐
- Kubernetes实战(一):k8s v1.11.x v1.12.x 高可用安装
说明:部署的过程中请保证每个命令都有在相应的节点执行,并且执行成功,此文档已经帮助几十人(仅包含和我取得联系的)快速部署k8s高可用集群,文档不足之处也已更改,在部署过程中遇到问题请先检查是否遗忘某个 ...
- python类型错误:'NoneType' object is not subscriptable
TypeError: 'NoneType' object is not subscriptable --> 原因:变量使用了系统内置的关键字list 解决:重新定义下这个变量
- java框架之SpringCloud(1)-微服务及SpringCloud介绍
微服务概述 是什么 业界大牛 Martin Fowler 这样描述微服务: 参考[微服务(Microservices)-微服务原作者Martin Flower博客翻译]. 下面是关于上述博客中的部分重 ...
- Python:遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序
编写了一个遍历一个目录下所有的文件及文件夹,然后计算每个文件的字符和line的小程序,先把程序贴出来. #coding=utf-8 ''' Created on 2014年7月14日 @author: ...
- centos7安装redist 以及redis扩展
wget http://download.redis.io/releases/redis-3.2.1.tar.gz 用wget下载 $ tar xzf redis-3.2.1.tar.gz 解 ...
- lua 特殊时间格式转换
[1]时间格式转换需求 工作中,因业务需要将时间格式进行转换.需求内容如下: 原格式:17:04:49.475 UTC Mon Mar 04 2019 转换格式:2019-03-04 17:04:4 ...
- mysql 终止 存储过程
[1]如下图所示 有时候,存储过程执行语句中有循环,且已启动.但出于某种原因,我们突然不想让其再继续执行,需要终止其线程. Good Good Study, Day Day UP. 顺序 选择 循环 ...
- Kubernetes应用健康检查
目录贴:Kubernetes学习系列 在实际生产环境中,想要使得开发的应用程序完全没有bug,在任何时候都运行正常,几乎 是不可能的任务.因此,我们需要一套管理系统,来对用户的应用程序执行周期性的健康 ...
- 解决 img 标签上下出现的间隙
我们在平常的开发过程中,经常需要使用多张图片,而使用多张图片的时候,一般会去使用一个列表来对我们的img进行承装.就算我们把img的外边距和内边距全部清空了,但是这时会发现图片上下单会多出一定的间隙. ...
- jmeter如何玩?
ApacheJMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可以用于测试静态和动态资源例如静态文件.J ...