使用JQuery ajaxFileUpload.js上传文件踩坑记录

0.182字数 826阅读 9451

前言

最近在做前端的时候要实现文件上传的功能,用了form和jquery的ajax传值效果都不理想,最后采用了ajaxFileUpload.js这个前端脚本来实现。在使用的时候遇到了几个坑,一路摸着石头过河,也算是解决了问题,遂记录下来。这个功能在实际工作种经常用到,希望能给需要做这方面的人有些帮助。

ajaxFileUpload.js 有很多同名的,网上很好找到。我附上一个我使用的版本。https://github.com/carlcarl/AjaxFileUpload

遇到的那些坑

  • 后端返回的json格式数据,用IE浏览器就变成了下载。用chrome浏览器会提示:Resource interpreted as Document but transferred with MIME type application/json。

  • 原生ajaxFileUpload只能上传单独文件,不支持用data来传其他的几个参数。

  • 使用了ajaxFileUpload上传后,每次上传完都会莫名其妙刷新页面。

问题的解决方案

后端返回的json格式数据,用IE浏览器就变成了下载

这个问题,我问了问度娘,度娘跟我说比较好解决。问题是出在后端返回数据的类型上。原来后台代码在返回json数据时,响应数据的ContentType如果是“application/json”,IE浏览器的新版本(IE10、IE11)会把该类型解释为文件下载操作。
原代码:

//Response内容类型设置
context.Response.ContentType = "application/json";

修改后的代码:

//Response内容类型设置
context.Response.ContentType = "text/html";

修改后就能解决这个问题。

原生ajaxFileUpload只能上传单独文件,不支持用data来传其他的几个参数

原以为这个插件支持jquery的ajax方法,参数可以用data来传,比如下面这样的

$.ajaxFileUpload({
                url: '/admin/UploadHandler.ashx',
                secureuri: false, //是否需要安全协议,一般设置为false
                fileElementId: 'file', //文件上传域的ID
                data: {
                    operation: 'UploadWLNumList',
                    ckno: $("#ckno").val(),
                    xmno: $("#xmno").val(),
                },
                dataType: 'json', //返回值类型
                success: function (data, status) {
                    //过程代码省略
                    alert("导入成功")
                }
            });

然而是我太天真了,通过网上的文章和查看源码发现:ajaxFileUpload.js本身根本就不支持附带参数。于是我还是去问了万能的度娘。

我:度娘度娘,ajaxFileUpload.js不支持多参数上传怎么办啊?
度娘:你需要去ajaxFileUpload.js里面修改部分代码,使他支持这个功能。

下面直接附上ajaxFileUpload.js修改的代码。
原代码:

createUploadForm: function (id, fileElementId) {
        //create form
        var formId = 'jUploadForm' + id;
        var fileId = 'jUploadFile' + id;
        var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
        var oldElement = $('#' + fileElementId);
        var newElement = $(oldElement).clone();
    
        $(oldElement).attr('id', fileId);

修改后的代码:

createUploadForm: function (id, fileElementId, data) {
        //create form
        var formId = 'jUploadForm' + id;
        var fileId = 'jUploadFile' + id;
        var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
        var oldElement = $('#' + fileElementId);
        var newElement = $(oldElement).clone();
        if (data) {
            for (var i in data) {
                $('<input type="hidden" name="' + i + '" value="' + data[i] + '"/>').appendTo(form);
            }
        }
        $(oldElement).attr('id', fileId);

改完后的ajaxFileUpload.js就能像ajax一样使用data来传其他参数了。

使用了ajaxFileUpload上传后,每次上传完都会莫名其妙刷新页面

这个问题我当时定位花了不少时间,结果发现问题出在最基础的标签上。因为ajaxFileUpload的上传原理是创建隐藏的表单和iframe然后用JS去提交,获得返回值。所以他只要有个input上传的标签id就行,根本不需要再套一个form标签。如果套了form标签后,自带的form标签并不是异步执行的,在提交后就会默认刷新界面,给使用者造成了困扰。
原代码:

<form id="uploadForm" method="post" enctype="multipart/form-data">
        <p>请选择要导入的文件</p>
        <input type="file" name="file" id="file">
        <button class="btn btn-primary radius" onclick="upload()" id="" name="aaa" value="导入文件">
        <i class="Hui-iconfont">&#xe645;</i> 导入文件</button>
</form>

修改后的代码:

        <p>请选择要导入的文件</p>
        <input type="file" name="file" id="file">
        <button class="btn btn-primary radius" onclick="upload()" id="" name="aaa" value="导入文件">
        <i class="Hui-iconfont">&#xe645;</i> 导入文件</button>

只要去掉form标签就行了,因为ajaxFileUpload会创建一个隐藏的表单和iframe然后用JS去提交,获得返回值。

推荐阅读更多精彩内容