基於formdata與blob的文件上傳與下載

首先介紹一下用到的基本知識

formdata

MDN上的定義:FormData 接口提供了一種表示表單數據的鍵值對的構造方式,經過它的數據可以使用 XMLHttpRequest.send() 方法送出。
簡單說就是用來構造http請求的參數(可以攜帶文件數據)。

常用方法:
FormData(form)
構造函數,參數可選,爲一個form對象Dom,會包含進該form的值
FormData.append(key,value)
用於添加新的屬性值,即使原屬性存在也不會覆蓋,而是新增鍵值對
formdata.delete(key)
用於刪除對象鍵值對

示例
html代碼

<form id="myForm" name="myForm">
  <div>
    <label for="username">Enter name:</label>
    <input type="text" id="username" name="username">
  </div>
  <div>
    <label for="useracc">Enter account number:</label>
    <input type="text" id="useracc" name="useracc">
  </div>
  <div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile">
  </div>
<input type="submit" value="Submit!">
</form>

js代碼

let form = document.getElementById('myForm');
let mrFormData = new FormData(form);
mrFormData.append('key1','value1');
mrFormData.append('key2','value2');

Blob

Blob是一個js用於構造流類型數據的對象
構造函數用法:
var aBlob = new Blob( array, options );
其中array是二進制數據,字符串數據等組成的數組
options是一個可選的BlobPropertyBag字典,

示例

let aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // 一個包含DOMString的數組
let oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // 得到 blob

有了這兩個對象,就可以開始分步驟實現文件上傳和下載了

1.生成一個formdata對象,用於向服務端傳遞數據

 var mrFormData = new FormData();
 mrFormData.append("upload-type", "TYPE_MERGE");
 mrFormData.append("upload-name", 'XXXX');
 mrFormData.append("upload-total", 'XXXX');
 mrFormData.append("upload-index", 'XXXX');

2.構造ajax的post請求

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var result = xmlhttp.response;
        var header = xmlhttp.getResponseHeader("content-disposition");
        var fileName = getValueByStr('filename',header);
        transArray2Csv(result,fileName);//生成csv
    }
}
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("X-Uni-Crsf-Token", (top.session && top.session.csrfToken) || "");
xmlhttp.responseType = "text";
xmlhttp.send(mrFormData);//向服務器發送數據

3.處理返回數據生成CSV並下載

function transArray2Csv(result, filename) {
    var blob = new Blob([result], {
        type: "text/plain"
    })
    const link = document.createElement("a")
    link.href = URL.createObjectURL(blob)
    link.download = filename // 這裏填保存成的文件名
    link.click()
    URL.revokeObjectURL(link.href)
}

至此,下載完成

注意事項(開發過程中遇到的問題)
  1. jq的ajax函數不支持返回流數據的處理,需要自己寫一個ajax請求;
  2. ajax進行post請求併發送數據時,需要在頭部添加content-type, xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  3. 當發送數據爲formdata數據時,瀏覽器會自動識別並添加頭content-type:multipart/form-data,並添加一個隨機字符串boundary用於分割formdata的每個屬性,且後臺基於此解析formdata;
  4. 若沒有上傳數據,採用get請求下載文件最佳;
  5. js生成文件並下載時,若有一個可以直接用於文件下載的接口,可以通過執行window.location.href = url下載文件,瀏覽器不會刷新,否則採用例子中的標籤方式下載。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章