2

在 SPA 网站(.NET Core 2,SPA React 模板)中使用FileStreamResult来自 C# 的文件,我从我的端点请求一个文件,这会在 C# 中触发此响应:

var file = await _docService.GetFileAsync(token.UserName, instCode.Trim()
.ToUpper(), fileSeqNo);
string contentType = MimeUtility.GetMimeMapping(file.FileName);
var result = new FileStreamResult(file.File, contentType);
var contentDisposition = new ContentDispositionHeaderValue("attachment");
Response.Headers[HeaderNames.ContentDisposition] = 
contentDisposition.ToString();
return result;

返回的响应是使用处理的msSaveBlob(特别是对于 MS,但即使我使用createObjectURL不同的浏览器,这也是一个问题(是的,我已经尝试了多种解决方案,但它们似乎都不起作用)。这是我用来发送请求,并FileStreamResult从服务器接收 PDF 。

if (window.navigator.msSaveBlob) {
  axios.get(url).then(response => {
      window.navigator.msSaveOrOpenBlob(
          new Blob([response.data], {type: "application/pdf"}),
          filename);
  });

问题是我得到的返回的PDF文件以某种方式有错误的编码。所以PDF将无法打开。

我尝试在 type: 末尾添加编码,{type: "application/pdf; encoding=UTF-8"}这在不同的帖子中有所建议,但是没有区别。

比较我以不同方式获取的 PDF 文件,我可以清楚地看到编码错误。大多数特殊字符都不正确。由响应头指示,PDF 文件应该在 中UTF-8,但我不知道如何实际找出和检查。

4

1 回答 1

8

在不知道 axios 的情况下,从它的自述页面看来,它使用 JSON 作为默认值responseType。这可能会改变内容,因为它现在被视为文本(当它无法转换为实际的 JSON 对象并保留响应数据的字符串/文本源时,axios 可能会退出)。

PDF 应该作为二进制数据加载,即使它可以是 8 位二进制内容或 7 位 ASCII,在任何情况下都应该被视为字节流,来自Adob​​e PDF 参考 sec。2.2.1

PDF 文件表示为 8 位二进制字节序列。PDF 文件旨在跨所有平台和操作系统移植。二进制表示旨在直接生成、传输和使用,无需在本地字符集、行尾表示或各种平台上使用的其他约定之间进行转换。[...]。

任何 PDF 文件也可以仅使用 7 位 ASCII [...] 字符代码的形式表示。这对于说明的目的很有用,就像在本书中一样。但是,不建议实际使用这种表示,因为它的效率低于正常的二进制表示。无论使用哪种表示形式,PDF 文件都必须作为二进制文件而不是文本文件进行传输和存储。[...]

因此,为了解决发生的转换,我建议responseType在执行请求时尝试指定配置条目:

axios.get(url, {responseType: "arraybuffer"}) ...

或以这种形式:

axios({
  method: 'get',
  url: url,
  responseType:'arraybuffer'
})
.then( ... )

blob如果您确定在此过程中保留了 mime-type,您也可以直接转到 response-type 。

于 2018-03-08T04:35:53.043 回答