打字稿:从API获取文件并读取它的原始文件名

问题描述 投票:0回答:1

我正在尝试使用tslib中的fetch方法从我在react-typescript应用程序中创建的API下载一些Excel文件。这是下载代码:

export const getBlobCors = url =>
  tryAjax<Blob>(
    () =>
      fetch(url, {
        credentials: 'omit',
        headers: new Headers({
          ...getAuthHeader(),
          responseType: 'blob'
        })
      }),
    async response => {
      if (response.ok) {
        const blob = await response.blob()
        return blob
      } else {
        throw new Error(DefaultErrorMsg)
      }
    }
  )

从这里调用此方法:

async function downloadReport(urlData: ReportUrlData) {
  const url = reportUrl(urlData)
  const blob = await getBlobCors(url)
  const blobUrl = window.URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.style.display = 'none'
  a.href = blobUrl
  a.download = 'Report.xlsx'
  document.body.appendChild(a)
  a.click()
  setTimeout(() => {
    document.body.removeChild(a)
    window.URL.revokeObjectURL(blobUrl)
  })
}

正如你现在所看到的,文件名是硬编码的a.download = 'Report.xlsx',但我需要的是将它分配给api已经返回的文件名。文件名确实存在于响应头Response headers中,但当我',试图读取它getBlobCors方法响应我得到null回来,实际上response.headers是空的。

async response => {
      if (response.ok) {
        const fileName = response.headers.get('Content-Disposition') // null
        const headers = response.headers // Headers {}
        const blob = await response.blob()
        return blob
      } 

有谁知道如何从响应或任何其他我可以得到它的文件名?

javascript reactjs typescript blob fetch
1个回答
0
投票

经过几乎整整一天的努力,我找到了解决问题的方法。问题出在我的后端。由于在CORS上使用Fetch API时访问响应头的限制,默认访问只允许预定义的标准头列表,如Content-TypeContent-LanguageLast-ModifiedCache-ControlExpiresPragma。需要在服务器上显式启用任何其他响应标头。在我的例子中,后端是ASP.NET Core,所以我在Startup.cs中添加了自定义CORS策略

services.AddCors(o => o.AddPolicy("WithExposedContentDispositionHeader", builder =>
{
     builder
     .AllowAnyOrigin()
     .WithExposedHeaders("content-disposition");
}));

并在控制器方法上启用此规则

 [EnableCors("WithExposedContentDispositionHeader")]
 public async Task<IActionResult> GetExcelReport([FromQuery] ReportInput input) {...}
© www.soinside.com 2019 - 2024. All rights reserved.