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 的问题. 问题解决 目前这个问题,首先需要分析应用所在的 ...
随机推荐
- javaweb(2)之Servlet入门
Hello Servlet 方式一 1.新建 web 工程,编写一个类,实现 javax.servlet.Servlet 接口: package com.zze.servlet; import jav ...
- JavaScript基础理解及技巧(入门)
1.java和JavaScript的区别: (1)js只需要解释就可以执行了,而java需要先编译成字节码文.JavaScript的运行只需要浏览器的支持,而java的运行需要JVM(java虚拟机) ...
- 深入理解Java虚拟机3-chap4-5-斗之气10段
一.虚拟机性能监控与故障处理 1.JDK的命令行工具:对jdk/lib/tools.jar的薄包装,Linux下可能是Shell编写,执行类似于Linux中的命令 2.可视化工具JConsole 打开 ...
- Mysql InnoDB 数据更新/删除导致锁表
一. 如下对账表数据结构 create table t_cgw_ckjnl ( CNL_CODE ) default ' ' not null comment '通道编码', CNL_PLT_CD ) ...
- python工具的选择
自己喜欢用pycharm,下载地址:https://www.jetbrains.com/products.html#lang=python 补丁地址:http://idea.lanyus.com/
- div “下沉”
最近在做一个计算器,按键整体布局如下: Div2,div3 display属性设置为inline-block.三个div “容器”没添加任何元素时,布局是符合预想的.添加上按键后,布局变成下面这样了: ...
- 01-python3.5-模块导入-while-for-range-break-continue
一.输入用户名和密码----导入getpass模块 #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:XZ """ ...
- Angular4的依赖注入
- 零基础快速入门web学习路线(含视频教程)
下面小编专门为广大web学习爱好者汇总了一条完整的自学线路:零基础快速入门web学习路线(含视频教程)(绝对纯干货)适合初学者的最新WEB前端学习路线汇总! 在当下来说web前端开发工程师可谓是高福利 ...
- hisi 生产固件生成
生产需求,需要16M bin 文件 给 spi flash烧写 一般有三种方式 1.把文件都导入flash,拆了flash 用烧录器读取,比较可靠! 2.编译时候合并,需要在空余地方填充0xFF拼成1 ...