以前在Vue的項目裏面用到過文件上傳,封裝好的組件用起來比較順手,查詢Element-UI文檔,十八般武器樣樣都有,一頓操做猛如虎,一看……跑偏了(⊙o⊙)…,個人意思就是用框架實現比較簡單,可是若是用jQuery的話,對原理可能會更瞭解一些,有須要的一塊兒看下吧~javascript
由於HTTP提供的是基於文本的通訊協議,而上傳文件傳輸的是二進制數據,因此須要使用multipart/form-data
編碼格式,其HTTP消息體格式以下:html
------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
java
<form> <input type="file" id="uplfile" name="uplfile"/> <button type="button" id="uplfileBtn">上傳</button> </form>
type="file"
的input有一個叫files
的DOM屬性,能夠獲取到所選的文件列表(Array),數組中每個對象都是file類型,jquery
var files = $("#uplfile").prop('files');
新版本的XMLHttpRequest對象可使用FormData
對象管理表單數據,能夠幫咱們進行二進制文件的multipart/form-data編碼,以下:web
$("#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。ajax
processData
:jQuery會將傳入的data對象轉爲字符串來發送HTTP請求,這裏咱們的data已是FormData對象處理好的multipart/form-data編碼,因此不須要轉換,設置爲false。數組
一般在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();
以上就是本文所有內容了,歡迎有興趣的朋友評論區留言交流~