【问题标题】:How to get the name of a file downloaded with Angular5如何获取使用 Angular5 下载的文件的名称
【发布时间】:2018-10-07 05:32:13
【问题描述】:

我的回复标题是:

HTTP/1.1 200 OK
Content-Disposition: attachment; filename="file.docx"
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Thu, 26 Apr 2018 10:37:00 GMT
ETag: W/"c61-16301871843"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Content-Length: 3169
Date: Thu, 26 Apr 2018 10:37:00 GMT
Connection: keep-alive

我试过这段代码,

 public download(id: string): Observable<Blob> {
    let headers = new Headers();
    const _baseUrl = (Api.getUrl(Api.URLS.download));
    headers.append('x-access-token', this.auth.getCurrentUser().token);
    headers.append('sale_id', id);
    return this.http.get(_baseUrl, { headers: headers, responseType: ResponseContentType.Blob})
      .map((res) => {
        console.log(res.headers) // show like in image
        return new Blob([res.blob()], { type: 'application/octet-stream' })
      });
  }

在控制台中显示:

没有显示内容处置!!

如何从标题中获取文件名?

【问题讨论】:

    标签: angular typescript http-headers blob


    【解决方案1】:

    希望这会节省您的时间,

    首先将文件保护程序导入到您的 components.ts 文件中

    import { saveAs } from 'file-saver';
    
    return this.http.get(url, { headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    }, responseType: 'blob', observe: 'response' })
      .pipe().subscribe({
        next: (response: any) => {
          let fileName = 'file';
          const contentDisposition = response.headers.get('Content-Disposition');
          if (contentDisposition) {
            const fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            const matches = fileNameRegex.exec(contentDisposition);
            if (matches != null && matches[1]) {
              fileName = matches[1].replace(/['"]/g, '');
            }
          }
          const fileContent = response.body;
          const blob = new Blob([fileContent], { type: 'application/octet-stream' });
          saveAs(blob, fileName);
        },
        error: (error) => {
          this.handleError(error);
        }
      });
    

    另外,设置 API 端标头,如

    'Access-Control-Expose-Headers', 'Content-Disposition'
    

    【讨论】:

      【解决方案2】:

      您的后端需要返回一个特定的标头Access-Control-Expose-Headers。如果你不这样做,Angular 不会公开标题,解释为什么你看不到它。

      You can find more information here(虽然有点老了)和even more information here

      【讨论】:

      • 当我在邮递员中尝试时,下载文件非常顺利
      • 正如我所说,问题在于 Angular。我很确定 Postman 对此并不担心。
      • 好的,谢谢您的回答。我现在试试。非常感谢
      【解决方案3】:

      试试这个:

       (res: Response) => {
        const contentDisposition = res.headers.get('content-disposition') || '';
        const matches = /filename=([^;]+)/ig.exec(contentDisposition);
        const fileName = (matches[1] || 'untitled').trim();
        return fileName;
      };
      

      【讨论】:

      • 正如@trichetriche 所说,您需要在后端公开 Access-Control-Expose-Headers
      【解决方案4】:

      实际上,Angular 中的响应正文不会返回您可能需要的所有数据。所以我们需要指定我们需要完整的响应。为此,您需要在服务中添加带有 observe: "response" as 'body' 的 HTTPOptions,

      var HTTPOptions = {
           headers: new HttpHeaders({'Accept': 'application/pdf; charset=UTF-8',}),
           observe: "response" as 'body',// to display the full response & as 'body' for type cast
           'responseType': 'blob' as 'json'
       }
      
       return this.http.get(url, HTTPOptions);
      

      那么你就可以得到完整的响应,通过订阅这个方法,

      this.service.download().subscribe((result: HttpResponse<any>) => {
       console.log(result);
       console.log(result.headers.getAll('Content-Disposition'));
      }, err => {});
      

      更多详情可以参考Angular Documentation

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-07
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多