[英]Javascript file download / blob creation
我有一個 Vue.JS 前端和一個 dotnet 核心 API。 我正在嘗試從 API 下載文件(文件的來源無關緊要,但我正在構建響應,如下所示:
[HttpGet]
[Route("[action]/{attachmentId:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> DownloadAttachment(int attachmentId)
{
try
{
var file = await _attachmentService.DownloadAttachment(attachmentId);
return File(file.FileContent, file.FileType, file.FileName);
}
catch (Exception e)
{
_logger.logError(e, "DownloadAttachment: attachmentId:{@attachmentId}", attachmentId);
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
在郵遞員中訪問此端點會給我預期的響應:
這是一個普通的PDF。 請注意,文件內容長度約為 290KB。
嘗試將此文件下載到 Vue.JS 前端(使用 axios),我嘗試了以下 2 種方法:
1.
首先,我嘗試使用名為js-file-download的 npm 庫,代碼如下:
import fileDownload from "js-file-download";
const downloadAttachment = async (attachmentId, filename) => {
try {
var result = await api.get(`/api/Attachments/DownloadAttachment/${attachmentId}`);
fileDownload(result.data, filename, result.headers.type);
} catch (error) {
console.error(error);
return error;
}
}
這段代碼給了我一個損壞的 PDF 文件,它有 2 個空白頁(原始 PDF 有 2 頁內容),看起來大約是它應該大小的兩倍:
2.
我還嘗試使用以下代碼創建一個 JavaScript blob(不包括上述庫):
const downloadAttachment = async (attachmentId, filename) => {
try {
var result = await api.get(`/api/Attachments/DownloadAttachment/${attachmentId}`);
let blob = new File([result.data], filename, { type: result.headers["content-type"] });
let exportUrl = URL.createObjectURL(blob);
window.location.assign(exportUrl);
URL.revokeObjectURL(exportUrl);
} catch (error) {
console.error(error);
return error;
}
}
文件方面,這給了我完全相同的 510kb 文件。 甚至控制台記錄 blob 的大小也顯示為 522881,而來自 api 標頭的響應顯示內容長度為 297167:
我無法弄清楚發生了什么或額外數據來自哪里。 其他文件類型(例如 excel 文件或圖像)也是如此,盡管有趣的是下載非常簡單的文件類型(例如 txt 或 csv 文件)不會導致此問題。
在發布我自己的問題之前查看“類似問題”,我發現了一些導致答案的提示。 結果我需要調整我使用 axios 進行的 API 調用以包含適當的響應類型。 更改以下內容解決了我的問題:
var result = await api.post(`/api/Attachments/DownloadAttachment/${attachmentId}`);
更改為:
var result = await api.post(`/api/Attachments/DownloadAttachment/${attachmentId}`, {
headers: {
"Content-Disposition": "attachment"
},
responseType: "blob"
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.