Angular (5) httpclient 观察和响应类型:'blob'
Angular (5) httpclient observe and responseType: 'blob'
上下文:我正在尝试从后端下载一个二进制文件(需要一些数据 post 编辑为 json-body)并使用指定的文件名将其保存为 file-saver在 content-disposition header 的后端。要访问 headers,我想我需要 HttpResponse。
但我无法对 Blob 使用 angular 的 HttpClient.post<T>(...): Observable<HttpResponse<T>>;
方法。
当我打电话时
this.httpclient.post<Blob>('MyBackendUrl',
params,
{observe: 'response', responseType: 'blob'});
the compiler complains about the 'blob' ('json' is accepted by the compiler):
error TS2345: Argument of type '{ observe: "response"; responseType: "blob"; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
Types of property 'observe' are incompatible.
Type '"response"' is not assignable to type '"body"'.
当我将选项放在自己的 object 中时,如 所示(但没有 "as" ...) post(...) :Observable 被调用,我无法访问 headers.
顺便说一句,即使是简单的例子 return this.http.get<Blob>('backendUrl', {responseType: 'blob'});
在 中对我不起作用。
使用的版本
- Angular版本:5.0.3(一周左右更新到最新5)
- 打字稿:2.4.2
- 网络包:3.8.1
当使用observe:response
时,不要键入调用(post<Blob>(...)
),因为返回的Observable 将是HttpResponse。所以这应该有效:
this.httpclient.post('MyBackendUrl',
params,
{observe: 'response', responseType: 'blob'}
);
为什么会这样,post 方法有两个版本,一个有通用类型,一个没有:
/**
* Construct a POST request which interprets the body as JSON and returns the full event stream.
*
* @return an `Observable` of all `HttpEvent`s for the request, with a body type of `T`.
*/
post<T>(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe: 'events';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<HttpEvent<T>>;
/**
* Construct a POST request which interprets the body as an `ArrayBuffer` and returns the full response.
*
* @return an `Observable` of the `HttpResponse` for the request, with a body type of `ArrayBuffer`.
*/
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe: 'response';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'arraybuffer';
withCredentials?: boolean;
}): Observable<HttpResponse<ArrayBuffer>>;
你可以像这样使用
responseType: 'blob' as 'json'
其他答案是正确的,但缺少示例。
主要答案 首先当设置responseType 时return 响应类型更改为Blob。要解决此问题,请添加 observe: 'response'
which returns HTTPResponse.
示例:
我偶然发现了这个问题,花了 6 个小时解决。
所以,这里我给出了一个从 headers 获取文件名并下载文件的例子:
downloadPDF(url: string): Observable<any> {
return this.http.get<any>(url, { responseType: 'blob', observe: 'response' }).pipe(
map((result:HttpResponse<Blob>) => {
console.log(result);
saveAs(result, "Quotation.pdf");
return result;
}));
这里的http
是HttpClient的实例,saveAs()
是FileSavernpm包的一个方法,和OP一样
还有一个问题,您可能只会在 result.headers 中遇到 5 headers(Cache-Control, Pragma, etc) 而不是您的自定义 header,例如x-filename
.
这个 CORS 背后的原因。基本上 CORS 不允许浏览器访问超过 header 的数量(在上面的 link 中列出)。
所以要解决这个问题,您必须将 server/API 更改为发送 Access-Control-Expose-Headers header 请求。
上下文:我正在尝试从后端下载一个二进制文件(需要一些数据 post 编辑为 json-body)并使用指定的文件名将其保存为 file-saver在 content-disposition header 的后端。要访问 headers,我想我需要 HttpResponse。
但我无法对 Blob 使用 angular 的 HttpClient.post<T>(...): Observable<HttpResponse<T>>;
方法。
当我打电话时
this.httpclient.post<Blob>('MyBackendUrl',
params,
{observe: 'response', responseType: 'blob'});
the compiler complains about the 'blob' ('json' is accepted by the compiler):
error TS2345: Argument of type '{ observe: "response"; responseType: "blob"; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'.
Types of property 'observe' are incompatible.
Type '"response"' is not assignable to type '"body"'.
当我将选项放在自己的 object 中时,如
顺便说一句,即使是简单的例子 return this.http.get<Blob>('backendUrl', {responseType: 'blob'});
在
使用的版本
- Angular版本:5.0.3(一周左右更新到最新5)
- 打字稿:2.4.2
- 网络包:3.8.1
当使用observe:response
时,不要键入调用(post<Blob>(...)
),因为返回的Observable 将是HttpResponse。所以这应该有效:
this.httpclient.post('MyBackendUrl',
params,
{observe: 'response', responseType: 'blob'}
);
为什么会这样,post 方法有两个版本,一个有通用类型,一个没有:
/**
* Construct a POST request which interprets the body as JSON and returns the full event stream.
*
* @return an `Observable` of all `HttpEvent`s for the request, with a body type of `T`.
*/
post<T>(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe: 'events';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<HttpEvent<T>>;
/**
* Construct a POST request which interprets the body as an `ArrayBuffer` and returns the full response.
*
* @return an `Observable` of the `HttpResponse` for the request, with a body type of `ArrayBuffer`.
*/
post(url: string, body: any | null, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe: 'response';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType: 'arraybuffer';
withCredentials?: boolean;
}): Observable<HttpResponse<ArrayBuffer>>;
你可以像这样使用
responseType: 'blob' as 'json'
其他答案是正确的,但缺少示例。
主要答案 首先当设置responseType 时return 响应类型更改为Blob。要解决此问题,请添加 observe: 'response'
which returns HTTPResponse.
示例: 我偶然发现了这个问题,花了 6 个小时解决。
所以,这里我给出了一个从 headers 获取文件名并下载文件的例子:
downloadPDF(url: string): Observable<any> {
return this.http.get<any>(url, { responseType: 'blob', observe: 'response' }).pipe(
map((result:HttpResponse<Blob>) => {
console.log(result);
saveAs(result, "Quotation.pdf");
return result;
}));
这里的http
是HttpClient的实例,saveAs()
是FileSavernpm包的一个方法,和OP一样
还有一个问题,您可能只会在 result.headers 中遇到 5 headers(Cache-Control, Pragma, etc) 而不是您的自定义 header,例如x-filename
.
这个 CORS 背后的原因。基本上 CORS 不允许浏览器访问超过 header 的数量(在上面的 link 中列出)。
所以要解决这个问题,您必须将 server/API 更改为发送 Access-Control-Expose-Headers header 请求。