事实上,这个功能还没有在 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 ]
})