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 的问题. 问题解决 目前这个问题,首先需要分析应用所在的 ...
随机推荐
- TCP/IP的分层管理
网络基础TCP/IP 我们通常所使用的网络(包括互联网)均是在TCP/IP协议族的基础上运作的.HTTP属于它内部的一个子集 TCP/IP协议族按层次分为:应用层,传输层,网络层和数据链路层(更好的划 ...
- 2、jeecg 笔记之 t:dictSelect 或 t:dgCol 自定义字典
1.需求 先说一下需求场景吧,我们知道 jeecg 中提供了下拉,其中包含两种使用场景: 一种是直接通过 t:dictSelect 使用,再就是 t:dgCol 用于表头的列表工具条标签: 总之就是 ...
- JavaWeb & Tomcat
1 JavaWeb概述 Java在服务器端的应用有Servlet,JSP和第三方框架等. Java的Web框架基本都遵循特定的路数:使用Servlet或者Filter拦截请求,使用MVC的思想设计架构 ...
- Socket,ServerSocket,WebSocket
一 区别 首先来说下区别吧, Socket和ServerSocket 指传输层网络接口协议,是基于套接字的服务端和客户端实现. 而WebScoket是应用层协议,是客户端-服务器的异步通信方法,用于双 ...
- 019-并发编程-java.util.concurrent之-Semaphore 信号量
一.概述 Semaphore是一个计数信号量.从概念上将,Semaphore包含一组许可证.如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证.每个release()方法都会 ...
- Sigleton bj
package com.bjsxt.base; class Sigleton{ private Sigleton(){}; private static Sigleton instance = new ...
- 前端学习历程--css①
---恢复内容开始--- 本文用自己的理解,总结网上或者自身经历的问题,加以汇总,方便查找: 一.浏览器默认样式 1.浏览器处理css&html a.css作用范围:盒子模式.浮动.定位.背景 ...
- keepalived 工作原理
keepalived主要通过vrrp协议为基础进行通信 所以先从VRRP协议说起: VRRP: 英文全称 Virtual Router Redundancy Protocol, .中文:虚拟路由冗余协 ...
- WDCP面板Web环境安装redis与phpredis扩展应用方法
http://www.ctyun.cn/bbs/thread-2882-1-1.html根据网友的要求需要在WDCP面板环境中安装人人商城程序,但是这个程序需要支持redis与phpredis扩展.根 ...
- JavaScript 初知
JavaScript 初知 1.JavaScript 独立的语言2.浏览器就是JavaScript的语言解释器3.JavaScript 代码存在于HTML中4.单行注释用“//”.多行注释 /* */ ...