之前在Vue的項目里面用到過文件上傳,封裝好的組件用起來比較順手,查詢Element-UI文檔,十八般武器樣樣都有,一頓操作猛如虎,一看……跑偏了(⊙o⊙)…,我的意思就是用框架實現比較簡單,但是如果用jQuery的話,對原理可能會更了解一些,有需要的一起看下吧~
1. multipart/form-data
因為HTTP提供的是基於文本的通信協議,而上傳文件傳輸的是二進制數據,所以需要使用multipart/form-data編碼格式,其HTTP消息體格式如下:
------WebKitFormBoundaryb0GZcypmEqOvNHIY
Content-Deiposition: form-data; name="file"; filename="icon.png"
Content-Type: image/png
------WebKitFormBoundaryb0GZcypmEqOvNHIY
multipart/form-data的請求頭包含一個特殊的頭信息Content-Type,其值為multipart/form-data,另外需要規定一個內容分割boundary用於分割請求體中多個不同的內容:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryb0GZcypmEqOvNHIY
2. input選擇並獲取文件
<form>
<input type="file" id="uplfile" name="uplfile"/>
<button type="button" id="uplfileBtn">上傳</button>
</form>
type="file"的input有一個叫files的DOM屬性,可以獲取到所選的文件列表(Array),數組中每一個對象都是file類型,
var files = $("#uplfile").prop('files');
3. jQuery上傳文件
新版本的XMLHttpRequest對象可以使用FormData對象管理表單數據,可以幫我們進行二進制文件的multipart/form-data編碼,如下:
$("#uplfileBtn").click(function(){
var files = $("#uplfile").prop('files');
var data = new FormData();
data.append('file', files[0]); //參數名:file
$.ajax({
url: URL,
type: 'POST',
data: data,
cache: false, //禁止瀏覽器對該URL的緩存
contentType: false,
processData: false,
success: function(){
//后續操作
}
});
});
contentType:jQuery中contentType默認為application/x-www-form-urlencoded,因此傳入的data會被轉為默認的HTTP編碼,這里我們不需要這種轉換,設置為false。
processData:jQuery會將傳入的data對象轉為字符串來發送HTTP請求,這里我們的data已經是FormData對象處理好的multipart/form-data編碼,所以不需要轉換,設置為false。
4. js中如何直接下載文件
通常在web前端需要下載服務端文件,都是通過指定<a>標簽的href屬性訪問服務端URL來下載保存文件的,也可以在js中:
document.location.href = Url + '?fileName=' + value;
上面這種方法用的是HTTP的GET請求,只能通過URL傳參,在相對復雜的場景中(需要傳多個參數在服務端動態下載指定文件),即參數比較多的時候,我們想要能夠通過ajaxPOST方式來傳遞參數。
但是用ajax請求的數據只能存放在JavaScript的內存中,可以通過js讀取,無法保存到硬盤,因為JavaScript本身無法直接和硬盤交互。那么有什么方法可以實現呢?一向方法總比困難多,我們可以通過模擬Form表單的提交來實現POST請求下載文件,如下:
<form id="myform" action="http://blog.kwin.wang/test/xxx.do" method="post">
<input type="hidden" name="type" value="trade"/>
<input type="hidden" name="time" value="20180818"/>
<input type="hidden" name="fileName" value="a.png"/>
</form>
主動提交Form表單:
$("#myform")[0].submit();
以上就是本文全部內容了,歡迎有興趣的朋友評論區留言交流~
