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 页面的回传值了

时间: 2025-01-11 07:15:41

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

asp.net中fileupload上传文件的方法

FileUpload 控件显示一个文本框控件和一个浏览按钮,使用户可以选择客户端上的文件并将它上载到 Web 服务器.用户通过在控件的文本框中输入本地计算机上文件的完整路径(例如,C:\MyFiles\test.txt)来指定要上载的文件.用户也可以通过单击“浏览”按钮,然后在“选择文件”对话框中定位文件来选择文件. 用户选择要上载的文件后,FileUpload 控件不会自动将该文件保存到服务器.您必须显式提供一个控件或机制,使用户能提交指定的文件.例如,可以提供一个按钮,用户单击它即可上载文件

MVC中如何上传文件

本文导读:在MVC中实现文件上传与传统的WebForm上传文件方法都差不多,在cshtml视图页面放一个file标签,然后在actionname方法中处理用户上传的文件.下面简单介绍MVC中上传文件的方法. 一.MVC中如何上传文件 1.在Web Forms中,当你把一个FileUpload控件拖到设计器中,你或许没有注意到在生成的HTML中会在form标签中加入一条额外属性 enctype="multipart/form-data". 而FileUpload控件本身会生成为<i

java开发中截取上传文件的文件名和后缀名

java开发中截取上传文件的文件名和后缀名 /** * Return the extension portion of the file's name . * * @see #getExtension */ public static String getExtension(File f) { return (f != null) ? getExtension(f.getName()) : ""; } public static String getExtension(String f

使用Ajax.BeginForm 中需要 上传文件 但 Request.files获取不到

使用Mvc里的插件jquery.unobtrusive-ajax.min.js 之前一直困在这里,一开始以为添加属性enctype="multipart/form-data"就可以 网上看到都是用另外一个插件jquery.form.js 于是,从某篇文章的附件中下载了jquery.form.js,弄了许久,还不行,顿时泪崩了, 最后在官网下载最新的jquery.form.js就解决了  ==|| 使用Ajax.BeginForm 中需要 上传文件 但 Request.files获取不到

【纯干货】4年前想解决的事情,今天才实验成功:浏览器原生分块上传文件

第一份软件开发工作的第一个星期(不算做试用期的一个星期,无薪水试用).因为不是软件专业,也没有经过培训和相关工作经验.老板不放心,但还是让我试一试.做的第一件事情就是上传文件,实时看进度,并且上传后预览.预览的文件类型有word,ppt,excel,flash,视频按帧获取预览图.office文件是在服务器端转成html后显示出来. 做的还满意,就留下来了,后来就在那个公司待了两年. 没解决的事情: 上传大文件,分块上传,浏览器原生不支持,需要借助第三方插件.最根本的原因就是浏览器端的js考虑的

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

以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  可以带参数 [HttpPost("upload")] public JsonResult uploadProject(IFormFile file, string userId) { if (file != null) { var fileDir = "D:\\aaa"

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

1. 常规方法,重写WebChromeClient 的 openFileChooser 方法 private class MyWebChromeClient extends WebChromeClient { // For Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { if (mUploadMessage != null) return; mUploadMe

SpringMvc (注解)中的上传文件

第一步:导入commons-fileupload-1.3.1.jar 和commons-io-2.2.jar 架包 第二步:在applicationContext.xml中 配置 <bean id=”multipartResolver” class=”org.springframework.web.multipart.commons.CommonsMultipartResolver”/> 第三步:在页面 <form>标签添加属性enctype=”multipart/form-dat

JAVA从局域网共享文件夹中下载上传文件以及java访问共享文件夹

1 package com.xx.test; 2 3 4 import java.io.BufferedInputStream; 5 import java.io.BufferedOutputStream; 6 import java.io.File; 7 import java.io.FileInputStream; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.io.InputS