在项目中使用了Juploader 1.0无刷新上传文件的js组件,在IE8以上没有问题,代码如下:

  1. function InitialUploadDirectly(OnUploadFunc, buttonID, allowedExts) {
  2. $.jUploader({
  3. button: buttonID, // 这里设置按钮id
  4. eventType: 1, //触发类型
  5. addeventbutton: buttonID, // 要绑定事件的元素的id
  6. filenamed: buttonID + 'divFileName', //存放选择的文件路径的文本框的id
  7. checkMethod: function () { return checkForm(); },
  8. afterChoose: function (fileName) { afterUpload(fileName, buttonID); },
  9.  
  10. allowedExtensions: allowedExts, // 设置允许上传的后缀,当然最好在服务器端也做验证
  11.  
  12. // 开始上传事件
  13. onUpload: function (fileName) {
  14. var url = "**.ashx";
  15. if (OnUploadFunc != null) {
  16. url = OnUploadFunc();
  17. }
  18. $.jBox.tip("正在上传文件,请稍候!", "loading");
  19. return url;
  20. },
  21.  
  22. // 上传完成事件
  23. onComplete: function (fileName, response) {
  24. // response是json对象,格式可以按自己的意愿来定义,例子为: { success: true, fileUrl:'' }
  25. console.log(response);
  26. if (response.Msg == "success") {
  27. AfterUploadCompleteSuccess(response.AddedFile.S_ID, fileName);
  28.  
  29. }
  30. else if (response.Msg == "error") {
  31. jBox.closeTip();
  32. jBox.error("文件大小不能超过50M", "错误提示");
  33. }
  34. else {
  35. jBox.closeTip();
  36. jBox.error(response.Msg, "错误提示");
  37. }
  38. },
  39.  
  40. // 系统信息显示(例如后缀名不合法)
  41. showMessage: function (message) {
  42.  
  43. jBox.tip(message, 'error');
  44. },
  45.  
  46. // 取消上传事件
  47. onCancel: function (fileName) {
  48. jBox.tip(fileName + ' 上传取消。', 'info');
  49. },
  50.  
  51. // 自己定义文字
  52. messages: {
  53. upload: '添加附件...',
  54. emptyFile: "{file} 为空,请选择一个文件.",
  55. invalidExtension: "{file} 后缀名不合法. 只有 {extensions} 是允许的.",
  56. onLeave: "文件正在上传,如果你现在离开,上传将会被取消。"
  57. }
  58. });
  59. }

但是使用Chrome(我测试的版本为31)浏览器测试的时候,虽然服务器已经接收到上传的文件,并且返回了json格式的数据对象,但是前台脚本中始终得不到返回值,response始终为{“Msg”:”error”},查看Jquploader的源码,发现response是在complete事件中try catch 中异常情况中赋的值,下面代码中黄色标识的部分

  1. var complete = function () {
  2. try {
  3. options.uploading = false;
  4. $('#jUploader-file' + options.id).show();
  5. options.button.children('span').text(options.messages.upload);
  6.  
  7. var iframe = $('#jUploaderIframe' + options.id).get(0);
  8. // when we remove iframe from dom
  9. // the request stops, but in IE load
  10. // event fires
  11. if (!iframe.parentNode) {
  12. return;
  13. }
  14.  
  15. // fixing Opera 10.53
  16. if ((iframe.contentDocument &&
  17. iframe.contentDocument.body &&
  18. iframe.contentDocument.body.innerHTML == "false")
  19. || (iframe.contentWindow.document &&
  20. iframe.contentWindow.document.body &&
  21. iframe.contentWindow.document.body.innerHTML == "false")) {
  22. // In Opera event is fired second time
  23. // when body.innerHTML changed from false
  24. // to server response approx. after 1 sec
  25. // when we upload file with iframe
  26. return;
  27. }
  28.  
  29. // iframe.contentWindow.document - for IE<7
  30. var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document;
  31. var response;
  32.  
  33. log("innerHTML = " + doc.body.innerHTML);
  34.  
  35. try {
  36. var json = doc.body.innerHTML.replace(/<pre>(.*)<\/pre>/g, '$1');
  37. response = eval("(" + json + ")");
  38. } catch (e) {
  39. response = { "Msg": "error" };
  40. //throw e;
  41. }
  42. console.log(response);
  43. // timeout added to fix busy state in FF3.6
  44. setTimeout(function () {
  45. $('#jUploaderForm' + options.id).remove();
  46. $('#jUploaderIframe' + options.id).remove();
  47. }, 10);
  48.  
  49. options.onComplete(options.fileName, response);
  50. }
  51. catch (e) {
  52. setTimeout(function () {
  53. $('#jUploaderForm' + options.id).remove();
  54. $('#jUploaderIframe' + options.id).remove();
  55. }, 10);
  56. response = { "Msg": "error" };
  57. options.onComplete(options.fileName, response);
  58. }
  59. };

继续调试发现下面这段代码中

var json = doc.body.innerHTML.replace(/<pre>(.*)<\/pre>/g, '$1');的json始终为空,但是实际上后台是返回了值的。

继续查看源码,明白了Juploader的基本思想,是在页面中创建iframe,再在iframe中构建一个form,form的action指向上传文件的后台服务器地址,如下:

  1. $(document.body).append(createIframe()).append(createForm());

并且在iframe的onload事件中绑定自定义的complete方法,如下:

  1. var createIframe = function () {
  2. var id = 'jUploaderIframe' + options.id;
  3. var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>').bind('load', complete);
  4.  
  5. return iframe;
  6. };

这样在iframe中的form加载完成后会执行iframe的onload事件(具体iframe的onload事件的用法,可自行百度,这里不多做解释了)。

但是在调试过程中却发现onload的事件总是先执行,也就是说complete方法在执行的时候form其实还没有加载完成,以下是控制台日志显示内容:

于是怀疑是因为代码顺序的问题造成的,再看一下具体的代码

createIframe方法中:

  1. var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>').bind('load', complete);

upload方法中:

  1. $(document.body).append(createIframe()).append(createForm());

于是调整代码在iframe append form 后,再bind iframe 的onload事件

createIframe方法中

  1. var iframe = $('<iframe id="' + id + '" name="' + id + '" src="javascript:false;" style="display:none"></iframe>')

去掉了bind  load 的事件

而在upload方法中:

  1. var ifrm = createIframe();
  2. $(document.body).append(ifrm).append(createForm());
  3. ifrm.bind("load", complete);

这样修改之后,上传完成事件onComplete 的response参数就可以正常获取form 中action 页面的回传值了

Juploader 1.0 谷歌(chrome)浏览器中成功上传文件后返回信息异常的更多相关文章

  1. IE浏览器上传文件后返回结果会自动弹出下载框

    服务器使用的是node,其它语言的后台没测试过. 在IE低版本浏览器下,当你上传一个文件后后台会返回一些数据,但是IE浏览器会弹出下载提示. 这个问题是之前处理的了,没有细究,今天有人问到这个问题,顺 ...

  2. nss_12 上传文件后返回jsonresult结果,IE中出现文件下载框

    因为控制器返回的是JsonResult, 但是在IE8中一直返回文件下载的对话框. 转到谷歌浏览器倒没有问题. 网上找的方法, 要么是跟到一个新的成功页面, 要么是直接返回html, 觉得应该有更好的 ...

  3. 在asp.net 中怎样上传文件夹

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  4. Android应用开发中webview上传文件的几种思路

    1. 常规方法,重写WebChromeClient 的 openFileChooser 方法 private class MyWebChromeClient extends WebChromeClie ...

  5. ASP.Net在web.config中设置上传文件的大小方法

    修改Webcong文件:<system.web><httpRuntime maxRequestLength="40960"   //即40MB,1KB=1024u ...

  6. tp中附件上传文件,表单提交

    public function tianjia(){ $goods=D('Goods'); if(!empty($_POST)){ if($_FILES['f_goods_image']['error ...

  7. 定制FileField中的上传文件名称

    FileField中的upload_to属性可以设定上传文件的存储目录和名称,它可以是个字符串,也可以是个callable,比如一个方法. 当upload_to的值设为一个方法时,就可以对上传文件的名 ...

  8. SpringMvc (注解)中的上传文件

    第一步:导入commons-fileupload-1.3.1.jar 和commons-io-2.2.jar 架包 第二步:在applicationContext.xml中 配置 <bean i ...

  9. 【Azure 应用服务】PHP应用部署在App Service for Linux环境中,上传文件大于1MB时,遇见了413 Request Entity Too Large 错误的解决方法

    问题描述 在PHP项目部署在App Service后,上传文件如果大于1MB就会遇见 413 Request Entity Too Large 的问题. 问题解决 目前这个问题,首先需要分析应用所在的 ...

随机推荐

  1. dyld_shared_cache_extract_dylibs failed

    文章来源:https://www.jianshu.com/p/e276a784fbee   s.png 数据线插上手机 Xcode->window   3.png   2.png 点击Unpai ...

  2. ShoppingCart类图

    1,组合关系,实心的棱形画在整体上面,发现很多人把它画错了 2,1..*或*代表的意义说明: 完整格式为:最小数量..最大数量 约束:前者必须小于后者,如1..*表示1个或多个,不会包含1..0这种情 ...

  3. hibernate重要知识点总结

    一.使用注解方式-----实体和表之间的映射 配置spring的applicationContext.xml文件: <bean id="sessionFactory" cla ...

  4. pip 更改国内镜像

    2 pip 更改国内镜像 pip 默认不使用国内镜像,但是我们可以自己设置 -[pypi 镜像使用帮助] 临时使用 pip install -i https://pypi.tuna.tsinghua. ...

  5. Cocos Creator 资源加载(笔记)

    cc.loader 加载资源动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下.resources 需要在 assets 文件夹中手工 ...

  6. 斐讯面试记录—TCP滑动窗口及拥塞控制

    TCP协议作为一个可靠的面向流的传输协议,其可靠性是由流量控制和滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现. 一.滑动窗口协议 1. “窗口”对应的是一段可以被发送者发送的字节序 ...

  7. MTCNN试用

    检测工作想借用MTCNN里的48-net,源码来自CongWeilin Git 下下来就能跑,真是良心 进入pepare_data准备好数据以后进入48-net,目录下有一个pythonLayer.p ...

  8. eclipse自定义快捷键(模板)

    window->Preferences->Java->Editor->Templates https://blog.csdn.net/changqing5818/article ...

  9. mybatis 查询优化主子表查询之association和collection

    很多开发人员之所以编写出低效的应用,有一大原因是并不理解怎样编写高效的SQL.以订单查询为例,我们经常需要查询某个用户的订单以及订单明细,并且以树形方式展现如下: 对于这种性质的功能,很多开发人员的做 ...

  10. 剑指offer(3)从尾到头打印链表

    题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ t ...