无法在Angular4 GET响应中查看“Content-Disposition”标头

时间:2017-08-26 07:12:54

标签: javascript angular browser download http-headers

我正在尝试在Angular应用中下载pdf文件。服务器(JBoss)使用

提供文件

Content-type : application/pdf and Content- Disposition

标头设置为附件。 在fiddler响应中我可以很好地看到这些标题。但是在我的订阅回调中,我看不到相同的标题。相反,标题包含两个属性,即: _headers and _normalizedHeaders

进行GET通话时。我这样做:

`this._http.get(url, {responseType: 'arraybuffer'}).subscribe((file: Response)=>{

    //Cant find headers in file here

});`

此外,我尝试将responseType设置为RequestContentType.Blob,它也没有任何区别。

对于我的下载实现,我有一段代码,一直用于下载AngularJS的附件。我只是在这里努力阅读Content-Disposition标题。

我还尝试设置{ observe : response },期望以这种方式获得详细的响应。但是,由于某些原因,在GET options中不允许设置该属性。

我在SO上看到很多答案,并尝试了大部分答案,但仍然无法获得标题。

P.S:直接在浏览器上访问API会让我下载文件,这意味着我的Java代码很好,这让我想知道上面的代码有什么问题。

请求建议。

3 个答案:

答案 0 :(得分:2)

在Evans建议的Access-Control-Expose-HeaderssetExposedHeaders的帮助下,我可以实现以下文件下载。

在Java代码中,您需要公开Access-Control-Expose-Headers,这可以使用CORS完成:

    CorsFilter corsFilter = new CorsFilter();
    corsFilter.setAllowedHeaders("Content-Type, Access-Control-Allow-Headers, Access-Control-Expose-Headers, Content-Disposition, 
    Authorization, X-Requested-With");
    corsFilter.setExposedHeaders("Content-Disposition");

这将在服务器响应中公开所需的标头。

在您的客户端上,您可以使用以下完整代码处理响应:

    private processDownloadFile() {
              const fileUrl = this._downloadUrl;
              this.http.get(fileUrl, ResponseContentType.ArrayBuffer).subscribe( (data: any) => {
                const blob = new Blob([data._body], { type: data.headers.get('Content-Type')});
                const contentDispositionHeader = data.headers.get('Content-Disposition');
                if (contentDispositionHeader !== null) {
                    const contentDispositionHeaderResult = contentDispositionHeader.split(';')[1].trim().split('=')[1];
                    const contentDispositionFileName = contentDispositionHeaderResult.replace(/"/g, '');
                    const downloadlink = document.createElement('a');
                    downloadlink.href = window.URL.createObjectURL(blob);
                    downloadlink.download = contentDispositionFileName;
                    if (window.navigator.msSaveOrOpenBlob) {
                        window.navigator.msSaveBlob(blob, contentDispositionFileName);
                    } else {
                        downloadlink.click();
                    }
                }
              });
    }   

当然,我在一个地方写了一切。您可能希望模块化各种回调。

希望有一天能帮到某人。

答案 1 :(得分:0)

你可以尝试这样吗

我们需要这个包文件保护程序,你安装像" npm install file-saver --save",然后你可以尝试

public downloadCSVFile(){
this.downloadPdf().subscribe(
    (res) => {      
        saveAs(res,'test.pdf')
    }
);
}

public downloadPdf(): any {
   let url='your url'
   let headers = new Headers();
   headers.append('Authorization', 'JWT ' + localStorage.getItem('id_token'));
   return this.http.get(url,{  headers: headers,responseType: ResponseContentType.Blob }).map(
    (res) => {
        return new Blob([res.blob()], { type: 'application/pdf' })
    })


  }

您需要从支持的(JBoss服务器)公开" Content- Disposition" 的标题

答案 2 :(得分:0)

对于您的服务器发送的可在Angular(或任何其他Web应用程序)中访问的任何自定义标头,它必须出现在Access-Control-Expose-Headers中,否则您的浏览器将不会将其传递给您的Angular应用程序并且您赢了“即使您的开发人员工具显示它也能检索它。