一、上傳文件的做法
1 前端代碼
<input id="myfiles" name="myfiles" type="file" onchange="upload();"/>
<input type="button" name="btn_abc" onclick="document.getElementById('myfiles').click();" style="xxxx" />
upload js方法
function upload() {
alert("haha");
$.ajaxFileUpload({
url : "xxxx",
secureuri : false,
fileElementId : 'myfiles',
dataType : 'JSON',
data: { …
},
success : function(data, status) {
},
error : function(data, status, e) {
….
}
});
return false;
};
2 界面

3 執行結果
我們發現確實彈框了,但是彈了不只一次,這是什么原因呢?

4 通過查看ajaxFileUpload源碼,其做法個人總結如下。
i 創建一個from表單,表單的action是我們一開始調用ajaxFileUpload方法是傳入的參數url
ii 通過jquery的clone方法,將原來的各種input復制到步驟1 創建的form表單下。
iii 將form表單append到一個iframe下
iv 通過form表單提交數據,發送同步請求去上傳資源,但創建的iframe和我們的頁面不在同一個層級,所以刷新了之后對我們的頁面是不影響的。
我使用的Chrome的版本如下

經過調試發現,出現這種彈框多次的原因是由於ajaxFileUpload插件的fileElementId造成的。
來看下源碼
AjaxFileUpload.js


此時會調用到JQuery的clone方法,

因此初步確定了是因為clone方法在復制節點的時候調用到了復制的input中的onchange方法或者是復制過來后副本的onchange方法。
在用低版本的Chrome測試了下,發現在clone方法,不會調用到onchange方法,版本如下

最后,總結以下出現上傳文件多次彈框的原因是:Chrome的版本升級后,對jquery的clone方法的解析執行跟以前不一樣。
5 解決方案
記錄之前的路徑,然后每次獲取當前路徑先跟之前的做對比,不相等才發請求
var prePath = $('#myfiles').val();
function upload() {
var curPath = $('#myfiles').val();
if (prePath == curPath) {
return false;
}
prePath = curPath;
$.ajaxFileUpload({
url : "xxxx", //submit to UploadFileServlet
secureuri : false,
fileElementId : 'myfiles',
dataType : 'JSON',
data: {
},
success : function(data, status) {
},
error : function(data, status, e) {
}
});
return false;
};
