事实上,HTTP支持中尚未实现此功能。
作为解决方法,您需要按照以下说明扩展Angular2的BrowserXhr
类,以将基础xhr对象上的responseType
设置为blob
:
import {Injectable} from 'angular2/core';
import {BrowserXhr} from 'angular2/http';
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.responseType = "blob";
return <any>(xhr);
}
}
然后您需要将响应有效负载包装到Blob
对象中,并使用FileSaver库打开下载对话框:
downloadFile() {
this.http.get(
'https://mapapi.apispark.net/v1/images/Granizo.pdf').subscribe(
(response) => {
var mediaType = 'application/pdf';
var blob = new Blob([response._body], {type: mediaType});
var filename = 'test.pdf';
saveAs(blob, filename);
});
}
必须将 FileSaver 库包含在 HTML 文件中:
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
请参考这个plunkr:http://plnkr.co/edit/tfpS9k2YOO1bMgXBky5Y?p=preview
不幸的是,这将设置所有AJAX请求的responseType
。为了能够设置此属性的值,还需要对XHRConnection
和Http
类进行更多更新。
作为参考,请参阅以下链接:
编辑
经过思考,我认为您可以利用分层注入器,并仅在执行下载的组件级别上配置此提供程序:
@Component({
selector: 'download',
template: '<div (click)="downloadFile() ">Download</div>'
, providers: [
provide(CustomBrowserXhr,
{ useClass: CustomBrowserXhr }
]
})
export class DownloadComponent {
@Input()
filename:string;
constructor(private http:Http) {
}
downloadFile() {
this.http.get(
'https://mapapi.apispark.net/v1/images/'+this.filename).subscribe(
(response) => {
var mediaType = 'application/pdf';
var blob = new Blob([response._body], {type: mediaType});
var filename = 'test.pdf';
saveAs(blob, filename);
});
}
}
这个重载只适用于此组件(在引导应用程序时不要忘记删除相应的提供项)。下载组件可以像这样使用:
@Component({
selector: 'somecomponent',
template: `
<download filename="'Granizo.pdf'"></download>
`
, directives: [ DownloadComponent ]
})