我正在尝试在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代码很好,这让我想知道上面的代码有什么问题。
请求建议。
答案 0 :(得分:2)
在Evans建议的Access-Control-Expose-Headers
和setExposedHeaders
的帮助下,我可以实现以下文件下载。
在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应用程序并且您赢了“即使您的开发人员工具显示它也能检索它。