【问题标题】:With Angular's new HttpClient, how can I get all headers when subscribing to the events?使用 Angular 的新 HttpClient,订阅事件时如何获取所有标头?
【发布时间】:2018-01-10 20:29:32
【问题描述】:

我正在使用 Angular 4.3.2 和新的 HttpClient 下载作为流发送的文件,我需要获取标题(特别是 Content-Disposition),但它们似乎不存在即使我可以在 Chrome 的开发工具中看到与请求一起正确发送的标头,也会得到响应。

这是代码:

downloadDocument(documentId: number) {
    const downloadDocumentUrl = `${ this.config.apiUrls.documents }/${ documentId }`;
    const downloadRequest = new HttpRequest('GET', downloadDocumentUrl, {
        reportProgress: true,
        responseType: 'blob'
    });

    let percentageDownloaded = 0;
    this.http.request(downloadRequest).subscribe(
        (event: HttpEvent < any > ) => {
            if (event) {
                switch (event.type) {
                    case HttpEventType.ResponseHeader:
                        const contentDispositionHeader = event.headers.get('Content-Disposition');
                        console.log(contentDispositionHeader); // Always null here although I expected it to be there.
                        break;

                    case HttpEventType.DownloadProgress:
                        if (event.total) {
                            percentageDownloaded = Math.round((event.loaded / event.total) * 100);
                        }
                        break;

                    case HttpEventType.Response:
                        const downloadedFile: Blob = event.body;
                        fileSaverSaveAs(downloadedFile, `${ documentId }.pdf`, true); // This is where I'd like to use content-disposition to use the actual file name.
                        break;
                }
            }
         ,
        (err) => {}
    );
}

调用此代码时,Chrome 会在开发工具的网络选项卡中报告以下响应标头:

访问控制允许凭据:true
访问控制允许来源:http://localhost:4200
内容处置:附件;文件名=doc5619362.pdf;文件名*=UTF-8''doc5619362.pdf
内容长度:88379
内容类型:应用程序/pdf
日期:格林威治标准时间 2017 年 8 月 3 日星期四 09:43:41
服务器:Kestrel
不同:产地
X-Powered-By:ASP.NET

关于如何访问响应中存在的所有标头有什么想法吗?不只是 Content-Disposition 不存在,除了 Content-Type 之外,所有其他标头都不存在。

谢谢!

更新

这是一个正在运行的 Plunker 演示该问题:https://plnkr.co/edit/UXZuhWYKHrqZCZkUapgC?p=preview

【问题讨论】:

  • event.headers.get(...) 是正确的方法
  • 正如马克西姆斯推荐的那样;文档:angular.io/api/http/Response#headers
  • @ManhLe 此链接适用于旧的Http 文档,OP 使用的是新的HttpClient,因此该文档的正确链接是:DOCS
  • 感谢@Maximus 的评论,正如您在我的示例代码中看到的那样,这是我正在采用的方法,但它不起作用,标题不存在。
  • 所以这意味着问题出在其他地方,您可以设置一个 plunker 吗?

标签: angular


【解决方案1】:

问题不在于 Angular,而在于 CORS 握手: 如果服务器没有明确允许您的代码读取标头,则浏览器会将它们隐藏起来。服务器必须在其响应中添加标头 Access-Control-Expose-Headers:&lt;header_name&gt;,&lt;header-name2&gt; 以便您阅读它们,但目前它只允许通过添加 Access-Control-Allow-Origin 来执行请求并读取响应的正文

【讨论】:

  • 感谢您的回答,@Pablo。不幸的是,在我的真实场景中,CORS 是允许的,文件下载也很好,但仍然没有标题。不过,在那个 Plunkr 中,我仍然应该得到标题。我找不到指向该示例的文件以允许使用 CORS。
  • 你确定吗?我的意思是 plunkr 方案不是一个有效的方案,该标头在那里不存在,因此任何其他问题都无法在那里重现
  • 我已将 plunkr 更新为允许 CORS 的请求:plnkr.co/edit/UXZuhWYKHrqZCZkUapgC?p=preview
  • 是的,它们会,因为它们是由服务器发送的。但是由于 CORS 限制,Chrome 会将它们从您的代码中隐藏(服务器必须显式公开它们)
  • 允许任何标头(请求标头被接受)与“公开任何标头”完全不同(任何人都可以读取响应标头)
猜你喜欢
  • 1970-01-01
  • 2011-12-10
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 2023-02-19
  • 2018-04-24
  • 1970-01-01
相关资源
最近更新 更多