简体   繁体   中英

Angular 5 'Content-Type': 'multipart/form-data' gets reset to 'application/json'

Hi I am having trouble trying to get my httpClient patch request to send FormData with content type 'multipart/form-data'.

I have specified the headers as shown:

 private httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache' }) };

And I do the following to save to the nodejs server:

 const formData: FormData = new FormData(); formData.append('materialFile', 'something'); return this.httpClient.patch<any>(this.apiUrl + loan.id, formData, this.httpOptions);

On my Nodejs/Express server I do the following:

 const Multer = require('multer'); router.patch('/:id', Multer().fields([{ name: "materialFile", maxCount: 1 }]), (req, res, next) => { console.log(req.files['materialFile']); });

When I inspect the request headers on the browser I see that the content-type is application/json.

Anybody knows why?

Angular tries to automatically set http header content-type according to request body, so there is absolutely no need to set it manually. If the content-type header is application/json in browser's devtools that means request body has been changed till angular's attempt to define the header. That change most probably happens in interceptors. So if you have an interceptor, that makes manipulation on the request, the issue is probably at that point.

As Hikmat G. pointed out, the problem is most likely steming from an Http interceptor, in my case, i found out that in my Authorization interceptor that i use to inject the JWT Token was setting the content-type to application/json as shown below :

    return req.clone({
        setHeaders: {
        'Content-Type' :  'application/json',
        'Accept': 'application/json',
        'Authorization': `Bearer ${ token }`,
        },
    });

and i did need it that way, except for a certain request where i was sending a file as part of a formdata object, where the content type had to be multipart/form-data , it would be automatically changed to json, so i added in a condition to avoid that problem and it seemed to be working :

        let json_blacklist = "/example/url";
        let reqHeaders = {
            setHeaders: {
            'Content-Type' :  'application/json',
            'Accept': 'application/json',
            'Authorization': `Bearer ${ token }`,
            },
        };

        if(req.url.includes(json_blacklist)) {
            delete reqHeaders.setHeaders["Content-Type"];
        }

        return req.clone(reqHeaders);

Tip : For requests where you're sending files, don't set the content-type to multipart/form-data, just remove the content type altogether and allow for the browser to set the content type by itself, this will help prevent webkit boundaries error as the browser will automatically set the boundaries, See #40561738 for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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