【问题标题】:How to receive blob responses using Angular's 2+ @angular/http module?如何使用 Angular 的 2+ @angular/http 模块接收 blob 响应?
【发布时间】:2016-03-13 00:14:47
【问题描述】:

我正在尝试从 Angular 2 应用程序中提供 pdf 下载...

此代码有效:

    var reportPost = 'variable=lsdkjf';

    var xhr = new XMLHttpRequest();

    xhr.open("POST", "http://localhost/a2/pdf.php", true);
    xhr.responseType = 'blob';
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    xhr.onreadystatechange = function() {//Call a function when the state changes.
        if(xhr.readyState == 4 && xhr.status == 200) {
            var blob = new Blob([this.response], {type: 'application/pdf'});
            saveAs(blob, "Report.pdf");
        }
    }

    xhr.send(reportPost);

但我希望使用 Angular 2 的内置 Http 客户端。

一点研究:

还有一些测试代码:

    var headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');

    this.http.post('http://localhost/a2/pdf.php', reportPost,  {
        headers: headers
        })
        .retry(3)
        // .map( (res:any) => res.blob() ) // errors out
        .subscribe(
          (dataReceived:any) => {
            var blob = new Blob([dataReceived._body], {type: 'application/pdf'});
            saveAs(blob, "Report.pdf");
          },
          (err:any) => this.logError(err),
          () => console.log('Complete')
        );

ps。 saveAs 函数来自这里:https://github.com/eligrey/FileSaver.js

【问题讨论】:

  • 似乎 blob() 方法尚未实现。见github.com/angular/angular/blob/master/modules/angular2/src/…。可以在此处找到跟踪实施状态的问题:github.com/angular/angular/issues/2803
  • 您到底是如何让“saveAs”工作的?我已经安装了模块,安装了打字,当我运行它时仍然得到“没有这样的功能:saveAs”......太烦人了......你如何将它包含在打字稿代码中? (我用的是webpack,还没弄明白)
  • 我刚刚忽略了来自 TS 编译器的错误。它仍然编译...马虎啊?

标签: angular rxjs


【解决方案1】:

随着 Angular2 final 的发布,我们可以定义例如一个服务:

@Injectable()
export class AngularService {

    constructor(private http: Http) {}

    download(model: MyModel) { //get file from service
        this.http.post("http://localhost/a2/pdf.php", JSON.stringify(model), {
            method: RequestMethod.Post,
            responseType: ResponseContentType.Blob,
            headers: new Headers({'Content-Type', 'application/x-www-form-urlencoded'})
        }).subscribe(
            response => { // download file
                var blob = new Blob([response.blob()], {type: 'application/pdf'});
                var filename = 'file.pdf';
                saveAs(blob, filename);
            },
            error => {
                console.error(`Error: ${error.message}`);
            }
        );
    }
}

此服务将获取文件,然后将其提供给用户。

zip 文件示例:How to use JAX-RS and Angular 2+ to download a zip file

【讨论】:

  • 谢谢!我错过了 responseType:ResponseContentType.Blob。
  • 有人能把这个标记为正确答案吗,我找这个很久了。
  • 从 '@angular/http' 导入 {ResponseContentType };
  • 我不得不使用 http.get(url, {responseType: "application/octet-stream"}),因为 http.get 无法识别 ResponseContentType 类型的 responseType,并且需要字符串。而且你不能设置除“json”之外的其他字符串,所以我不得不欺骗 TS 编译器。
  • 我收到此错误[ts] Property 'blob' does not exist on type 'Blob'. 有人知道为什么吗?
【解决方案2】:

有了@4.3, @5HttpClientModule,我最终做了:

this.http.post(`${environment.server}/my/download`,
                data, 
                {responseType: 'blob', observe: 'response'})
              .map( res => ({content: res.body, 
                             fileName: res.headers.get('content-filename')}));

【讨论】:

    【解决方案3】:

    请看这里:https://stackoverflow.com/a/45666313/4420532

    return this._http.get('/api/images/' + _id, {responseType: 'blob'}).map(blob => {
      var urlCreator = window.URL;
      return this._sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob));
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多