如何删除 HTTP 拦截器中设置的用于以角度 4 上传文件的内容类型
How to remove Content Type set in HTTP Interceptors for uploading a file in angular4
在我的应用程序中,我们在拦截器中设置了 content-type = application/json
。
但是上传文件的内容类型应该是 multipart/form-data
,即当我们尝试上传表单数据时需要 contant-type = multipart/form-data
。
我的问题是如何在执行 post 上传文件请求时删除拦截器中设置的内容类型。
谢谢,
哈沙瓦丹
删除现有的header
if (!req.headers.has('Content-Type')) {
req = req.clone({ headers: req.headers.delete('Content-Type','application/json') });
添加新的Headers
req = req.clone({ headers: req.headers.set('Content-Type', 'multipart/form-data')})
检查header的当前值。
req.headers.get('Accept')
我遇到了类似的问题,最后通过在 body 上调用 toString() 来检查它是否是表单数据来解决它。
我确定有一种更简洁的方法来检查对象的类型,但这对我来说效果很好:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let ignore =
typeof req.body === "undefined"
|| req.body === null
|| req.body.toString() === "[object FormData]" // <-- This solves your problem
|| req.headers.has("Content-Type");
if (ignore) {
return next.handle(req);
}
const cloned = req.clone({
headers: req.headers.set("Content-Type", 'application/json')
});
return next.handle(cloned);
}
请注意,我还忽略了任何手动指定 Content-Type 的请求。
我正在使用 Node.JS back-end,它通常接受 application/json
content-type。一个端点需要一个文件,需要通过 multipart/form-data
形式发送。这可以通过使用 FormData 接口来实现。
所以在将数据从 Angular 发送到我的 back-end 之前,我使用了 FormData
接口:
onSubmit() {
// ... some logic before
// Need to post multipart/form-data to our server, so let's create a FormData instance:
const formData = new FormData();
formData.append('icon', this.selectedIcon, this.selectedIcon.name); // the actual file
formData.append('name', this.createGroupForm.get('name').value); // other data from a Angular reactive form
// Send the FormData to the service
this.groupService.post(formData).subscribe((group) => {
console.log({
group,
});
});
}
现在使用 Angular HttpInterceptor
检测您发送的是普通数据还是 FormData 并根据实例更改 content-type
header 实际上很容易request.body
:
export class ExampleInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
/**
* Let's assume that we need to set the contentType to application/json for every request.
*/
let contentType = 'application/json';
/**
* But when the data of the body is an instance of FormData, we can assume that we are uploading an file.
* Therefore, we need to change the contentType to multipart/form-data.
*/
if (request.body instanceof FormData) {
// we are sending a file here
contentType = 'multipart/form-data';
}
const clonedRequest= request.clone({
setHeaders: {
'content-type': contentType, // set the content-type here
},
});
return next.handle(clonedRequest);
}
}
您可以使用 in-built 函数 delete 由 Angular 的 HttpHeaders 提供。
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'my-required-content-type'
})
};
httpOptions.headers.delete('Content-Type');
这样,您可以使用名称作为键来设置或删除特定的 headers。
在拦截器headers中检查传入的内容类型,如下所示:
intercept(request:HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
// check whether we have form data
if (request.body instanceof FormData)
{
return request.clone({
setHeaders:{
'ContentType' : 'multipart/form-data',
Authorization: `Bearer ${token}`
}
});
}
else{
return request.clone({
setHeaders:{
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
}
});
}
}
希望对你有用!
在我的应用程序中,我们在拦截器中设置了 content-type = application/json
。
但是上传文件的内容类型应该是 multipart/form-data
,即当我们尝试上传表单数据时需要 contant-type = multipart/form-data
。
我的问题是如何在执行 post 上传文件请求时删除拦截器中设置的内容类型。
谢谢, 哈沙瓦丹
删除现有的header
if (!req.headers.has('Content-Type')) {
req = req.clone({ headers: req.headers.delete('Content-Type','application/json') });
添加新的Headers
req = req.clone({ headers: req.headers.set('Content-Type', 'multipart/form-data')})
检查header的当前值。
req.headers.get('Accept')
我遇到了类似的问题,最后通过在 body 上调用 toString() 来检查它是否是表单数据来解决它。
我确定有一种更简洁的方法来检查对象的类型,但这对我来说效果很好:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let ignore =
typeof req.body === "undefined"
|| req.body === null
|| req.body.toString() === "[object FormData]" // <-- This solves your problem
|| req.headers.has("Content-Type");
if (ignore) {
return next.handle(req);
}
const cloned = req.clone({
headers: req.headers.set("Content-Type", 'application/json')
});
return next.handle(cloned);
}
请注意,我还忽略了任何手动指定 Content-Type 的请求。
我正在使用 Node.JS back-end,它通常接受 application/json
content-type。一个端点需要一个文件,需要通过 multipart/form-data
形式发送。这可以通过使用 FormData 接口来实现。
所以在将数据从 Angular 发送到我的 back-end 之前,我使用了 FormData
接口:
onSubmit() {
// ... some logic before
// Need to post multipart/form-data to our server, so let's create a FormData instance:
const formData = new FormData();
formData.append('icon', this.selectedIcon, this.selectedIcon.name); // the actual file
formData.append('name', this.createGroupForm.get('name').value); // other data from a Angular reactive form
// Send the FormData to the service
this.groupService.post(formData).subscribe((group) => {
console.log({
group,
});
});
}
现在使用 Angular HttpInterceptor
检测您发送的是普通数据还是 FormData 并根据实例更改 content-type
header 实际上很容易request.body
:
export class ExampleInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
/**
* Let's assume that we need to set the contentType to application/json for every request.
*/
let contentType = 'application/json';
/**
* But when the data of the body is an instance of FormData, we can assume that we are uploading an file.
* Therefore, we need to change the contentType to multipart/form-data.
*/
if (request.body instanceof FormData) {
// we are sending a file here
contentType = 'multipart/form-data';
}
const clonedRequest= request.clone({
setHeaders: {
'content-type': contentType, // set the content-type here
},
});
return next.handle(clonedRequest);
}
}
您可以使用 in-built 函数 delete 由 Angular 的 HttpHeaders 提供。
const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'my-required-content-type' }) }; httpOptions.headers.delete('Content-Type');
这样,您可以使用名称作为键来设置或删除特定的 headers。
在拦截器headers中检查传入的内容类型,如下所示:
intercept(request:HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
// check whether we have form data
if (request.body instanceof FormData)
{
return request.clone({
setHeaders:{
'ContentType' : 'multipart/form-data',
Authorization: `Bearer ${token}`
}
});
}
else{
return request.clone({
setHeaders:{
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
}
});
}
}
希望对你有用!