使用JQuery ajaxFileUpload.js上传文件踩坑
前言
最近在做前端的时候要实现文件上传的功能,用了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"></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"></i> 导入文件</button>
只要去掉form标签就行了,因为ajaxFileUpload
会创建一个隐藏的表单和iframe
然后用JS去提交,获得返回值。