简体   繁体   English

Angular 从 API 接收文件

[英]Angular receive file from API

My api is generating a pdf file and returning it.我的 api 正在生成 pdf 文件并返回它。 The headers I receive in postman are...我在 postman 中收到的标头是...

Content-Type →application/pdf
Content-Length →2099
Content-Disposition →attachment; filename=Ticket_20200409210413358621_Home_3.pdf
Cache-Control →public, max-age=43200
Expires →Fri, 10 Apr 2020 09:04:13 GMT
Access-Control-Allow-Origin →*

And I can save the file contents no problem from postman.我可以从 postman 保存文件内容没有问题。

However, when I try to get this in angular there is an issue.但是,当我尝试在 angular 中得到这个时,就会出现问题。

I set the headers like...我将标题设置为...

setRequestHeaderPDF() {
  return new HttpHeaders({
    'Authorization': 'Bearer ' + localStorage.getItem('id_token'),
    'Content-Type': 'application/pdf',
    'Accept': 'application/pdf'
  })
}

Then I am trying two different things.然后我正在尝试两种不同的东西。

First is with responseType: 'blob' .首先是responseType: 'blob' This returns the blob no issue.这将返回 blob 没有问题。 The issue is, as you can see above, the filename is in the response headers.问题是,正如您在上面看到的,文件名在响应标头中。 With the blob response I cannot get the headers.使用 blob 响应,我无法获取标题。

Second I am not setting the responseType and hoping to get it out of the response text/body but that throws the following error其次,我没有设置 responseType 并希望将其从响应文本/正文中取出,但这会引发以下错误

message: "Unexpected token % in JSON at position 0" stack: "SyntaxError: Unexpected token % in JSON at position 0↵ at JSON.parse ()↵ at XMLHttpRequest.l " message: "Unexpected token % in JSON at position 0" stack: "SyntaxError: Unexpected token % in JSON at position 0↵ at JSON.parse ()↵ at XMLHttpRequest.l "

So my question is, how can I get a file from an API and have access to the headers and the data?所以我的问题是,如何从 API 获取文件并访问标题和数据?

Update: Turns out it was the authentication proxy that must have been stripping the headers or something.更新:原来是身份验证代理必须剥离标头或其他东西。 When I bypass that I can get the file now just fine.当我绕过它时,我现在可以得到文件就好了。

Well I found out that if using CORS you have to expose certain headers.好吧,我发现如果使用 CORS 您必须公开某些标头。 The API is in python flask so I added CORS(app, expose_headers=['Content-Disposition', 'x-suggested-filename'] as is answered here How to change downloading name in flask? The API is in python flask so I added CORS(app, expose_headers=['Content-Disposition', 'x-suggested-filename'] as is answered here How to change downloading name in flask?

In postman I get在 postman 我得到

Content-Type →application/pdf
Content-Length →2093
Content-Disposition →attachment; filename=Ticket_20200410171501039158_Home_3.pdf
Cache-Control →public, max-age=43200
Expires →Sat, 11 Apr 2020 05:15:01 GMT
x-suggested-filename →Ticket_20200410171501039158_Home_3.pdf
Access-Control-Allow-Origin →*
Access-Control-Expose-Headers →Content-Disposition, x-suggested-filename
Via →1.1 google
Alt-Svc →clear

And in my angular app I switched over to using XMLHttpRequest() for this one.在我的 angular 应用程序中,我切换到使用 XMLHttpRequest() 来处理这个。

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('id_token'));
xhr.setRequestHeader('Content-Type', 'application/pdf');
xhr.setRequestHeader('Accept', 'application/pdf');
xhr.responseType = 'blob';
xhr.onload = function (this, event) {
    var blob = this.response;
    console.log(this.getAllResponseHeaders());
    var contentDispo = this.getResponseHeader('Content-Disposition');
    var fileName = contentDispo.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1];
    saveAs(blob, fileName);
}
xhr.send();

This seems to be working now.这似乎现在起作用了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM