在项目中使用了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. javaweb(2)之Servlet入门

    Hello Servlet 方式一 1.新建 web 工程,编写一个类,实现 javax.servlet.Servlet 接口: package com.zze.servlet; import jav ...

  2. JavaScript基础理解及技巧(入门)

    1.java和JavaScript的区别: (1)js只需要解释就可以执行了,而java需要先编译成字节码文.JavaScript的运行只需要浏览器的支持,而java的运行需要JVM(java虚拟机) ...

  3. 深入理解Java虚拟机3-chap4-5-斗之气10段

    一.虚拟机性能监控与故障处理 1.JDK的命令行工具:对jdk/lib/tools.jar的薄包装,Linux下可能是Shell编写,执行类似于Linux中的命令 2.可视化工具JConsole 打开 ...

  4. Mysql InnoDB 数据更新/删除导致锁表

    一. 如下对账表数据结构 create table t_cgw_ckjnl ( CNL_CODE ) default ' ' not null comment '通道编码', CNL_PLT_CD ) ...

  5. python工具的选择

    自己喜欢用pycharm,下载地址:https://www.jetbrains.com/products.html#lang=python 补丁地址:http://idea.lanyus.com/

  6. div “下沉”

    最近在做一个计算器,按键整体布局如下: Div2,div3 display属性设置为inline-block.三个div “容器”没添加任何元素时,布局是符合预想的.添加上按键后,布局变成下面这样了: ...

  7. 01-python3.5-模块导入-while-for-range-break-continue

    一.输入用户名和密码----导入getpass模块 #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:XZ """ ...

  8. Angular4的依赖注入

  9. 零基础快速入门web学习路线(含视频教程)

    下面小编专门为广大web学习爱好者汇总了一条完整的自学线路:零基础快速入门web学习路线(含视频教程)(绝对纯干货)适合初学者的最新WEB前端学习路线汇总! 在当下来说web前端开发工程师可谓是高福利 ...

  10. hisi 生产固件生成

    生产需求,需要16M bin 文件 给 spi flash烧写 一般有三种方式 1.把文件都导入flash,拆了flash 用烧录器读取,比较可靠! 2.编译时候合并,需要在空余地方填充0xFF拼成1 ...