从 HttpClient post 响应中保存 csv 文件
Save csv file from HttpClient post response
我有一个网站,用户可以在其中请求一些数据作为 csv-file。然后数据被 return 编辑为并且应该 downloaded/saved 到一个文件。
我正在发送一个 post 请求并订阅,但似乎每次都在 catch 方法中失败。
请求header、删除授权等:
POST /api/@£$ HTTP/1.1
Connection: keep-alive
Content-Length: 144
Accept: application/json, text/plain, */*
Origin: https://@£$
Authorization: @£$
Content-Type: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;
with a body containing parameters, so the response is correct.
回复:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/csv
Content-Encoding: gzip
Vary: Origin,Accept-Encoding
Server: Kestrel
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin:
Request-Context:
Content-Disposition: attachment; filename=export_20181120_103716.csv
X-Powered-By: ASP.NET
Set-Cookie:
Date: Tue, 20 Nov 2018 10:37:16 GMT
我是不是漏掉了一些重要的东西?我需要设置响应类型吗?这个 api 只会 return csv-file 数据,所以真的不需要检查文件类型。
编辑:
添加发送请求的代码。
dataExport(parameters) {
const send = {
'id': parameters.ids,
'from': parameters.from,
'to': parameters.to
};
this.adalService.post(url, send,
{ headers: new HttpHeaders({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json'}) })
.do(() => { this.success('success'); })
.catch((error) => {
this.error(error);
return Observable.of(null);
})
.subscribe(r => {
const blob = new Blob([r], {type: 'text/csv'});
const url = window.URL.createObjectURL(blob);
window.open(url);
});
}
EDIT: added responseType: 'text'
to the post-request. This does not trigger the catch due to wrong reponse format. Is this the correct type? typescript did not let me use text/csv or application/csv. And im worried that when the file gets realy big, a blob will not have enough room to save the data.
设法使用 responseType header 以及 file-saver npm 包解决了我的问题。该解决方案目前可行,但由于这是用户选择的数据,文件大小可能会变得很大...
...post(url, send,
{ headers: new HttpHeaders({ 'Authorization': `Bearer ${token}`, 'Content-Type': contentType }), observe: 'response', responseType: 'text'})
.subscribe(r => { saveAs(new Blob([r.body], { type: 'text/csv' }), 'download.csv')});
我有一个网站,用户可以在其中请求一些数据作为 csv-file。然后数据被 return 编辑为并且应该 downloaded/saved 到一个文件。
我正在发送一个 post 请求并订阅,但似乎每次都在 catch 方法中失败。
请求header、删除授权等:
POST /api/@£$ HTTP/1.1
Connection: keep-alive
Content-Length: 144
Accept: application/json, text/plain, */*
Origin: https://@£$
Authorization: @£$
Content-Type: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;
with a body containing parameters, so the response is correct.
回复:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/csv
Content-Encoding: gzip
Vary: Origin,Accept-Encoding
Server: Kestrel
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin:
Request-Context:
Content-Disposition: attachment; filename=export_20181120_103716.csv
X-Powered-By: ASP.NET
Set-Cookie:
Date: Tue, 20 Nov 2018 10:37:16 GMT
我是不是漏掉了一些重要的东西?我需要设置响应类型吗?这个 api 只会 return csv-file 数据,所以真的不需要检查文件类型。
编辑: 添加发送请求的代码。
dataExport(parameters) {
const send = {
'id': parameters.ids,
'from': parameters.from,
'to': parameters.to
};
this.adalService.post(url, send,
{ headers: new HttpHeaders({ 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json'}) })
.do(() => { this.success('success'); })
.catch((error) => {
this.error(error);
return Observable.of(null);
})
.subscribe(r => {
const blob = new Blob([r], {type: 'text/csv'});
const url = window.URL.createObjectURL(blob);
window.open(url);
});
}
EDIT: added
responseType: 'text'
to the post-request. This does not trigger the catch due to wrong reponse format. Is this the correct type? typescript did not let me use text/csv or application/csv. And im worried that when the file gets realy big, a blob will not have enough room to save the data.
设法使用 responseType header 以及 file-saver npm 包解决了我的问题。该解决方案目前可行,但由于这是用户选择的数据,文件大小可能会变得很大...
...post(url, send,
{ headers: new HttpHeaders({ 'Authorization': `Bearer ${token}`, 'Content-Type': contentType }), observe: 'response', responseType: 'text'})
.subscribe(r => { saveAs(new Blob([r.body], { type: 'text/csv' }), 'download.csv')});