根據http協議的定義,完成請求消息體的封裝和解析,將二進制內容保存至文件。數組
關鍵字:服務器
multipart/form-dataapp
含義:ide
multipart表示資源有多種元素組成,form-data使用post方式或HTML Forms上傳文件。函數
結構:post
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2ahjiirVMKa4Qn78
Content-Disposition: form-data
爲固定值,表示一個表單元素,name
表示表單元素的 名稱,回車換行後面就是name
的值,若是是上傳文件就是文件的二進制內容。this
Content-Type
:表示當前的內容的 MIME 類型(type/subtype)通用+子類,是圖片仍是文本仍是二進制數據(text/.. application/... image/... video/...)。spa
解析:code
客戶端發送請求到服務器後,服務器拿到請求的消息體進行解析,解析出哪些是普通表單哪些是附件。通常不須要自行解析,有第三方庫可用。orm
關鍵字:
XMLHttpRequest
XMLHttpRequest2有了升級,首先就是能夠讀取和上傳二進制數據,能夠使用·FormData·對象管理表單數據。
示例:
<div> 選擇文件(可多選): <input type="file" id="f1" multiple/><br/><br/> <button type="button" id="btn-submit">上 傳</button> </div>
<script> function submitUpload() { //得到文件列表,注意這裏不是數組,而是對象 var fileList = document.getElementById('f1').files; if(!fileList.length){ alert('請選擇文件'); return; } var fd = new FormData(); //構造FormData對象 fd.append('title', document.getElementById('title').value); //多文件上傳須要遍歷添加到 fromdata 對象 for(var i =0;i<fileList.length;i++){ fd.append('f1', fileList[i]);//支持多文件上傳 } var xhr = new XMLHttpRequest(); //建立對象 xhr.open('POST', 'http://localhost:8100/', true); xhr.send(fd);//發送時 Content-Type默認就是: multipart/form-data; xhr.onreadystatechange = function () { console.log('state change', xhr.readyState); if (this.readyState == 4 && this.status == 200) { var obj = JSON.parse(xhr.responseText); //返回值 console.log(obj); if(obj.fileUrl.length){ alert('上傳成功'); } } } } //綁定提交事件 document.getElementById('btn-submit').addEventListener('click',submitUpload); </script>
藉助XMLHttpRequest2,實現單文件或多文件的上傳進度條。
說明
div.progress
js
內處理增長進度處理的監聽函數xhr.upload.onprogress
event.lengthComputable
這是一個狀態,表示發送的長度有了變化,可計算event.loaded
表示發送了多少字節event.total
表示文件總大小event.loaded
和event.total
計算進度,渲染div.progress
<div> 選擇文件(可多選): <input type="file" id="f1" multiple/><br/><br/> <div id="progress"> <span class="red"></span> </div> <button type="button" id="btn-submit">上 傳</button> </div>
<script> function submitUpload() { var progressSpan = document.getElementById('progress').firstElementChild; var fileList = document.getElementById('f1').files; progressSpan.style.width='0'; progressSpan.classList.remove('green'); if(!fileList.length){ alert('請選擇文件'); return; } var fd = new FormData(); //構造FormData對象 fd.append('title', document.getElementById('title').value); for(var i =0;i<fileList.length;i++){ fd.append('f1', fileList[i]);//支持多文件上傳 } var xhr = new XMLHttpRequest(); //建立對象 xhr.open('POST', 'http://10.70.65.235:8100/', true); xhr.onreadystatechange = function () { console.log('state change', xhr.readyState); if (xhr.readyState == 4) { var obj = JSON.parse(xhr.responseText); //返回值 console.log(obj); if(obj.fileUrl.length){ //alert('上傳成功'); } } } xhr.onprogress=updateProgress; xhr.upload.onprogress = updateProgress; function updateProgress(event) { console.log(event); if (event.lengthComputable) { var completedPercent = (event.loaded / event.total * 100).toFixed(2); progressSpan.style.width= completedPercent+'%'; progressSpan.innerHTML=completedPercent+'%'; if(completedPercent>90){//進度條變色 progressSpan.classList.add('green'); } console.log('已上傳',completedPercent); } } //注意 send 必定要寫在最下面,不然 onprogress 只會執行最後一次 也就是100%的時候 xhr.send(fd);//發送時 Content-Type默認就是: multipart/form-data; } //綁定提交事件 document.getElementById('btn-submit').addEventListener('click',submitUpload); </script>
xhr.upload.onprogress
要寫在xhr.send
方法前面,不然event.lengthComputable
狀態不會改變,只有在最後一次才能得到,也就是100%
的時候.