前言
最近在做前端的時(shí)候要實(shí)現(xiàn)文件上傳的功能,用了form和jquery的ajax傳值效果都不理想,最后采用了ajaxFileUpload.js這個(gè)前端腳本來(lái)實(shí)現(xiàn)。在使用的時(shí)候遇到了幾個(gè)坑,一路摸著石頭過(guò)河,也算是解決了問(wèn)題,遂記錄下來(lái)。這個(gè)功能在實(shí)際工作種經(jīng)常用到,希望能給需要做這方面的人有些幫助。
ajaxFileUpload.js有很多同名的,網(wǎng)上很好找到。我附上一個(gè)我使用的版本。https://github.com/carlcarl/AjaxFileUpload
遇到的那些坑
后端返回的json格式數(shù)據(jù),用IE瀏覽器就變成了下載。用chrome瀏覽器會(huì)提示:Resource interpreted as Document but transferred with MIME type application/json。
原生
ajaxFileUpload只能上傳單獨(dú)文件,不支持用data來(lái)傳其他的幾個(gè)參數(shù)。使用了
ajaxFileUpload上傳后,每次上傳完都會(huì)莫名其妙刷新頁(yè)面。
問(wèn)題的解決方案
后端返回的json格式數(shù)據(jù),用IE瀏覽器就變成了下載
這個(gè)問(wèn)題,我問(wèn)了問(wèn)度娘,度娘跟我說(shuō)比較好解決。問(wèn)題是出在后端返回?cái)?shù)據(jù)的類型上。原來(lái)后臺(tái)代碼在返回json數(shù)據(jù)時(shí),響應(yīng)數(shù)據(jù)的ContentType如果是“application/json”,IE瀏覽器的新版本(IE10、IE11)會(huì)把該類型解釋為文件下載操作。
原代碼:
//Response內(nèi)容類型設(shè)置
context.Response.ContentType = "application/json";
修改后的代碼:
//Response內(nèi)容類型設(shè)置
context.Response.ContentType = "text/html";
修改后就能解決這個(gè)問(wèn)題。
原生ajaxFileUpload只能上傳單獨(dú)文件,不支持用data來(lái)傳其他的幾個(gè)參數(shù)
原以為這個(gè)插件支持jquery的ajax方法,參數(shù)可以用data來(lái)傳,比如下面這樣的
$.ajaxFileUpload({
url: '/admin/UploadHandler.ashx',
secureuri: false, //是否需要安全協(xié)議,一般設(shè)置為false
fileElementId: 'file', //文件上傳域的ID
data: {
operation: 'UploadWLNumList',
ckno: $("#ckno").val(),
xmno: $("#xmno").val(),
},
dataType: 'json', //返回值類型
success: function (data, status) {
//過(guò)程代碼省略
alert("導(dǎo)入成功")
}
});
然而是我太天真了,通過(guò)網(wǎng)上的文章和查看源碼發(fā)現(xiàn):ajaxFileUpload.js本身根本就不支持附帶參數(shù)。于是我還是去問(wèn)了萬(wàn)能的度娘。
我:度娘度娘,
ajaxFileUpload.js不支持多參數(shù)上傳怎么辦???
度娘:你需要去ajaxFileUpload.js里面修改部分代碼,使他支持這個(gè)功能。
下面直接附上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來(lái)傳其他參數(shù)了。
使用了ajaxFileUpload上傳后,每次上傳完都會(huì)莫名其妙刷新頁(yè)面
這個(gè)問(wèn)題我當(dāng)時(shí)定位花了不少時(shí)間,結(jié)果發(fā)現(xiàn)問(wèn)題出在最基礎(chǔ)的標(biāo)簽上。因?yàn)?code>ajaxFileUpload的上傳原理是創(chuàng)建隱藏的表單和iframe然后用JS去提交,獲得返回值。所以他只要有個(gè)input上傳的標(biāo)簽id就行,根本不需要再套一個(gè)form標(biāo)簽。如果套了form標(biāo)簽后,自帶的form標(biāo)簽并不是異步執(zhí)行的,在提交后就會(huì)默認(rèn)刷新界面,給使用者造成了困擾。
原代碼:
<form id="uploadForm" method="post" enctype="multipart/form-data">
<p>請(qǐng)選擇要導(dǎo)入的文件</p>
<input type="file" name="file" id="file">
<button class="btn btn-primary radius" onclick="upload()" id="" name="aaa" value="導(dǎo)入文件">
<i class="Hui-iconfont"></i> 導(dǎo)入文件</button>
</form>
修改后的代碼:
<p>請(qǐng)選擇要導(dǎo)入的文件</p>
<input type="file" name="file" id="file">
<button class="btn btn-primary radius" onclick="upload()" id="" name="aaa" value="導(dǎo)入文件">
<i class="Hui-iconfont"></i> 導(dǎo)入文件</button>
只要去掉form標(biāo)簽就行了,因?yàn)?code>ajaxFileUpload會(huì)創(chuàng)建一個(gè)隱藏的表單和iframe然后用JS去提交,獲得返回值。