我有一个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);
}
}
访问Postman中的此端点给我预期的响应:
这是常规的PDF。注意文件内容长度约为290kb。
尝试将此文件下载到vue.js frontend(使用Axios),我尝试了以下2种方法:
1。
首先,我尝试使用npm库,称为 js-file-download 带有以下代码:
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;
}
}
//i.sstatic.net/unqsx.png 这使我完全是损坏的510kb文件。即使是记录斑点的控制台的大小为522881,而API标头的响应的内容长度为297167:
我无法弄清楚发生了什么或额外数据的来源。其他文件类型(例如Excel文件或图像)也会发生同样的情况,尽管有趣的是下载非常简单的文件类型,例如TXT或CSV文件并不会引起此问题。
I've a Vue.JS frontend and a dotnet core API. I'm trying to download a file from the API (the source of the file is irrelevant, but I'm constructing the response as follows:
[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);
}
}
Accessing this endpoint in postman give's me the expected response:


It's a regular PDF. Note the file content length is around 290KB.
Attempting to download this file to Vue.JS frontend (using axios), I've tried the following 2 methods:
1.
First, I tried making use of npm library called js-file-download with the following code:
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;
}
}
This code give's me a broken PDF file, which has 2 blank pages (the original PDF has 2 pages of content) which appears to be roughly double the size it's supposed to be:

2.
I also tried by creating a JavaScript blob (excluding the above mentioned library) with the following code:
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;
}
}
File wise, this give's me exactly the same broken 510kb file. Even console logging the blob shows a size of 522881 while the response from the api's headers shows a content length of 297167:

I cannot figure out what is going on or where the extra data is coming from. The same happens to other file types such as excel files or images, though interestingly downloading very simple file types such as txt or csv files does not cause this issue.
发布评论
评论(1)
在发布自己的问题之前,请仔细研究“类似的问题”,我发现了一些导致答案的暗示。原来,我需要调整我使用Axios进行的API调用,以包括适当的响应类型。更改以下问题解决了我的问题:
更改为:
Looking through the "Similar Questions" before posting my own question I found a hint of something that led to an answer. Turns out I needed to adjust me API call that I make with axios to include the appropriate response type. Changing the following fixed my issue:
changes to: