Typescript: извлеките файл из API и прочитайте его исходное имя файла

#javascript #reactjs #typescript #blob #fetch

#javascript #reactjs #typescript #большой двоичный объект #извлечение

Вопрос:

Я пытаюсь загрузить некоторый файл Excel из API, который я создал в своем приложении react-typescript, используя метод выборки из tslib. Вот код загрузки:

 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.
Имя файла действительно существует в заголовке ответа
Заголовки ответов
но когда я пытаюсь прочитать это 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
      } 
  

Кто-нибудь знает, как прочитать имя файла из ответа или любого другого, который я могу получить?

Ответ №1:

Потратив на это почти целый день, я нашел способ решить проблему. Проблема была в моем серверной части. Из-за ограничения доступа к заголовкам ответов при использовании Fetch API через CORS, где по умолчанию разрешен доступ только к предопределенному списку стандартных заголовков, таких как Content-Type , Content-Language , Last-Modified , Cache-Control Expires Pragma и,,,,,,,,,,,,,. Любые другие заголовки ответа должны быть включены на сервере явно. В моем случае серверная часть была ASP.NET Ядро, поэтому я добавил пользовательскую политику CORS в Startup.cs

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

И включил это правило в методе контроллера

  [EnableCors("WithExposedContentDispositionHeader")]
 public async Task<IActionResult> GetExcelReport([FromQuery] ReportInput input) {...}