How to remove Content Type set in HTTP Interceptors for uploading a file in angular4
To Remove Existing header
if (!req.headers.has('Content-Type')) { req = req.clone({ headers: req.headers.delete('Content-Type','application/json') });
Adding new Headers
req = req.clone({ headers: req.headers.set('Content-Type', 'multipart/form-data')})
To check the current value of the header.
req.headers.get('Accept')
I had a similar problem and ended up solving it by calling toString() on the body to check whether it is form data.
I'm sure there is a cleaner way to check the type of an object, but this worked well enough for me:
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);}
Note that I also ignore any requests where the Content-Type was manually specified.
I'm using a Node.JS back-end which accepts normally the application/json
content-type. One endpoint required a file, which needs to be send via a multipart/form-data
form. This can be achieved by using the FormData interface.
So before sending the data from Angular to my back-end, I used the FormData
interface:
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, }); });}
Now it's actually easy with an Angular HttpInterceptor
to detect if you are sending normal data or FormData, and changing the content-type
header based on the instance of 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); }}