Почему URL.createObjectURL начал давать имя моего файла как GUID? - PullRequest
0 голосов
/ 18 июня 2020

Это работало нормально, но внезапно перестало. История соответствующих файлов не выявила очевидных изменений, которые могли бы это вызвать. Вместо настоящего имени файла, скажем «upload.txt», я получаю GUID без расширения. Таким образом, браузер никогда не сможет открыть файл, как и система, когда он загружает, а не открывает.

Он отправляет имя файла правильно:

enter image description here

На стороне сервера:

[HttpGet("download/{fileId}")]
    public async Task<IActionResult> DownloadFile(int fileId)
    {
        var file = await _fileRepository.GetByIdAsync(fileId).ConfigureAwait(true);
        if (file == null)
            return NotFound();

        var path = _fileService.GetUploadedFilePath(file.FileNameInStorage);
        if (!System.IO.File.Exists(path))
            return NotFound();

        var memory = await PopulateMemoryStream(path).ConfigureAwait(true);
        memory.Position = 0;

        var contentType = FileUtils.GetContentTypeByExtension(file.Extension);
        var displayName = file.OriginalFileName;

        if (!Path.HasExtension(displayName))
            displayName += file.Extension;

        System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
        {
            FileName = displayName,
            Inline = true  // false = prompt the user for downloading;  true = browser to try to show the file inline
        };
        Response.Headers.Add("Content-Disposition", cd.ToString());
        Response.Headers.Add("X-Content-Type-Options", "nosniff");

        return File(memory, contentType, displayName);
    }

На стороне клиента:

  downloadFile(fileId: number): void {
this.fileService.transmitFile(fileId).subscribe(res => {
  const fileURL = URL.createObjectURL(res);
  window.open(fileURL, '_blank');
});
  }

transmitFile(fileId: number): any {
return this.http.get(`${this.apiUrl}/file/download/${fileId}`, { headers: { 'Accept': 'application/octet-stream' }, observe: 'response', responseType: 'arraybuffer' })
.pipe(
  map((res) => {
    return new Blob([res.body], { type: res.headers.get('content-type') });
  })
);

}

1 Ответ

0 голосов
/ 19 июня 2020

Вот как я изменил интерфейс, чтобы разрешить загрузку с расширениями. К сожалению, файлы по-прежнему получают GUID для имени файла, но они имеют расширение при загрузке или правильном открытии в браузере. Вам просто нужно убедиться, что вы устанавливаете правильный тип контента.

downloadFile(fileId: number): Observable<HttpResponse<ArrayBuffer>> {
      return this.http.get(`${this.apiUrl}/file/download/${fileId}`, { headers: { 'Accept': 'application/octet-stream' }, observe: 'response', responseType: 'arraybuffer' 
    });
  }

  downloadFile(fileId: number): void {
    this.fileService.downloadFile(fileId).subscribe(res => {
      const blob = new Blob([res.body], { type: res.headers.get('content-type') });
      const file = new File([blob], this.resume.originalFileName, { type: res.headers.get('content-type') });
      const fileURL = URL.createObjectURL(file);
      window.open(fileURL, '_blank');
  });
}

Бонус: вот код на стороне сервера для установки типа контента. Большинство случаев проверено.

public static string GetContentTypeByExtension(string ext)
    {
        switch (ext)
        {
            case ".png":
                return "image/png";
            case ".jpg":
            case ".jpeg":
                return "image/jpeg";
            case ".pdf":
                return "application/pdf";
            case ".doc":
            case ".dot":
            case ".rtf":
                return "application/msword";
            case ".docx":
                return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            case ".docm":
            case ".dotm":
                return "application/vnd.ms-word.document.macroEnabled.12";
            case ".tif":
            case ".tiff":
                return "image/tiff";
            case ".txt":
                return "text/plain";
            case ".xls":
            case ".xlt":
                return "application/vnd.ms-excel";
            case ".xlsx":
                return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            case ".xltx":
                return "application/vnd.openxmlformats-officedocument.spreadsheetml.template";
            case ".xlsm":
                return "application/vnd.ms-excel.sheet.macroEnabled.12";
            case ".xltm":
                return "application/vnd.ms-excel.template.macroEnabled.12";
            default:
                return "application/octet-stream";
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...