[英]Prompt file download with XMLHttpRequest
我知道 jQuery 的 ajax 方法無法處理下載,我不想添加 jQuery 插件來執行此操作。
我想知道如何使用 XMLHttpRequest 發送 POST 數據以下載文件。
這是我嘗試過的:
var postData = new FormData();
postData.append('cells', JSON.stringify(output));
var xhr = new XMLHttpRequest();
xhr.open('POST', '/export/', true);
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
console.log(e);
console.log(xhr);
}
xhr.send(postData);
我正在使用 Django,該文件似乎已成功發送回客戶端。 在 Chrome 的網絡選項卡中,我可以在預覽選項卡(我期望)中看到亂碼。 但我想發回一個 zip 文件,而不是 zip 文件的文本表示。 這是 Django 后端:
wrapper = FileWrapper(tmp_file)
response = HttpResponse(wrapper, content_type='application/zip')
response['Content-Disposition'] = "attachment; filename=export.zip"
response['Content-Length'] = tmp_file.tell()
return response
我已經搜索了幾個小時,但沒有找到有關如何使用 XMLHttpRequests 執行此操作的正確示例。 我不想使用 POST 操作創建適當的 html 表單,因為表單數據相當大,並且是動態創建的。
上面的代碼有問題嗎? 我錯過了什么? 我只是不知道如何將數據作為下載實際發送到客戶端。
如果您在發送請求之前將XMLHttpRequest.responseType
屬性設置為'blob'
,那么當您返回響應時,它將表示為一個 blob。 然后,您可以將 blob 保存到臨時文件並導航到該文件。
var postData = new FormData();
postData.append('cells', JSON.stringify(output));
var xhr = new XMLHttpRequest();
xhr.open('POST', '/export/', true);
xhr.setRequestHeader('X-CSRFToken', csrftoken);
xhr.responseType = 'blob';
xhr.onload = function (e) {
var blob = e.currentTarget.response;
var contentDispo = e.currentTarget.getResponseHeader('Content-Disposition');
// https://stackoverflow.com/a/23054920/
var fileName = contentDispo.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1];
saveOrOpenBlob(blob, fileName);
}
xhr.send(postData);
這是saveOrOpenBlob
的示例實現:
function saveOrOpenBlob(blob, fileName) {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function (fs) {
fs.root.getFile(fileName, { create: true }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.addEventListener("writeend", function () {
window.location = fileEntry.toURL();
}, false);
fileWriter.write(blob, "_blank");
}, function () { });
}, function () { });
}, function () { });
}
如果您不關心讓瀏覽器在文件是可查看的文件類型時導航到該文件,那么創建一個始終直接保存到文件的方法要簡單得多:
function saveBlob(blob, fileName) {
var a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = fileName;
a.dispatchEvent(new MouseEvent('click'));
}
更新:自從引入Blob API以來,此答案不再准確。 詳情請參閱史蒂文的回答。
原始答案:
XHR 請求不會觸發文件下載。 我找不到明確的要求,但是XMLHttpRequest上的W3C 文檔也沒有描述對 content-disposition=attachment 響應的任何特殊反應
如果不是 POST 請求,您可以通過window.open()
在單獨的選項卡中下載文件。 這里建議使用帶有target=_blank
的隱藏表單
download: function(){ var postData = new FormData(); var xhr = new XMLHttpRequest(); xhr.open('GET', downloadUrl, true); xhr.responseType = 'blob'; xhr.onload = function (e) { var blob = xhr.response; this.saveOrOpenBlob(blob); }.bind(this) xhr.send(postData); } saveOrOpenBlob: function(blob) { var assetRecord = this.getAssetRecord(); var fileName = 'Test.mp4' var tempEl = document.createElement("a"); document.body.appendChild(tempEl); tempEl.style = "display: none"; url = window.URL.createObjectURL(blob); tempEl.href = url; tempEl.download = fileName; tempEl.click(); window.URL.revokeObjectURL(url); },
試試這個它對我有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.