首先介紹一下用到的基本知識
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)
}
至此,下載完成
注意事項(開發過程中遇到的問題)
- jq的ajax函數不支持返回流數據的處理,需要自己寫一個ajax請求;
- ajax進行post請求併發送數據時,需要在頭部添加content-type,
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
; - 當發送數據爲formdata數據時,瀏覽器會自動識別並添加頭
content-type:multipart/form-data
,並添加一個隨機字符串boundary用於分割formdata的每個屬性,且後臺基於此解析formdata; - 若沒有上傳數據,採用get請求下載文件最佳;
- js生成文件並下載時,若有一個可以直接用於文件下載的接口,可以通過執行
window.location.href = url
下載文件,瀏覽器不會刷新,否則採用例子中的標籤方式下載。