Axios: Don't send default header

Created on 19 Jul 2016  ·  64Comments  ·  Source: axios/axios

If a header has been set as a default, there does not appear to be any way to skip it on an individual request. Setting null or undefined doesn't do anything.

headers

Most helpful comment

transformRequest: [(data, headers) => {
    delete headers.common.Authorization
    return data
}]

works for me

All 64 comments

Could you provide some code example that shows that behaviour? What default header are you trying to unset?

If I set axios.defaults.headers.common['Content-Type'] = 'application/json', I cannot unset that that header for an individual request, I can only set it to another value.

How did you tried to unset the header? Using something like this?

axios.request('/path', {
  headers: {
    'Content-Type': null
  }
});

Yes. That did not work

Sorry I missed the method in my example. Could have been that what made it not work?

I have tried setting the method as well. I suspect it has to do with an Object.assign() somewhere just not paying attention to the undefined value.

@tyrsius what version of axios are you using? I just wrote a test to try and reproduce this and it passed. I'm wondering if this may have been fixed in a newer version.

For reference here is my test:

it('should remove default headers when config indicates', function (done) {
  var instance = axios.create();
  instance.defaults.headers.common['Content-Type'] = 'application/json';

  instance.post('/foo/bar/', {
    firstName: 'foo',
    lastName: 'bar'
  }, {
    headers: {
      'Content-Type': null
    }
  });

  getAjaxRequest().then(function (request) {
    testHeaderValue(request.requestHeaders, 'Content-Type', null);
    done();
  });
});

I had this problem too.
I'm trying to remove the header 'Authorization' from 'common' but the only way that I've found to make it work is delete the property from the axios.defaults.header, make the request, and then add the property back again.
This will be easier when this bug is fixed

This is also a problem for me (using axios v0.14.0), especially for endpoints that use Access-Control-Allow-Headers, in which case I need to make sure certain headers aren't sent with the request at all.

i am using version 15.2 and when i do

headers: {
      'Content-Type': null
    }

it does set the header value to null. but i really need the header name to be removed completely.

for example when using s3 and generating a presigned url to post a file to a bucket you can not have an Authenticate header. but i have a default Authorization set because the vast majority of my requests require it for my own api.

the way i got around this is by doing the following

    var instance = axios.create();
    instance.defaults.headers.common = {};

    instance.put(signedUrl, file, {headers: {'Content-Type': file.type}})
        .then(function (result) {
            console.log(result);
        })
        .catch(function (err) {
            console.log(err);
        });

Edit: this does not work as expected. the issue is that when you clear the headers

instance.defaults.headers.common = {};

it removes it at a global level. this will log me out as i use a header for Auth.

to get around this issue until there is a better way of handling global config i am passing the required headers on every call, not ideal.

545

I had the same problem but solved with

delete axios.defaults.headers.common["Authorization"]; // or which ever header you have to remove

I have the exact situation as @SepiaGroup
I tried to overwrite it with null and '' but then AWS sees null as my Authorization and complains.
I tried to delete it from the instance but then my Authorization is deleted globally so I get 403 on my own server.

I guess my workaround will be to use an old XHR for this but it makes me sad :(

+1 Also stuck with not being able to clear the default header for a specific call.

+1

+1

I'm also seeing this behavior in the latest version (0.16.2). Sadness ensues :(

just delete it

delete instance.defaults.headers.common.Authorization
````

the way below is not working.
----
I think we could create a logout method that recreate the axios instance to replace the old one.

let instance = axios.create({options})

function: logout () {
instance = axios.create({options})
}
```

@lzp4ever that would work in most instances, I expect. But in cases where someone has added request and response interceptors, or done more configuration of the instance beyond simply passing in config options, wouldn't your approach require that all of that be redone?

Just wondering if perhaps @axelgenus's solution is cleaner and requires less "resetting" of an entire Axios instance from which you're attempting to remove a particular customized header from.

Would be nice to be able to NOT send the default header without deleting properties :)

+1

+1

+1. It does seem sad that you cannot remove the headers for an instance. This means that all instances have a reference to the global variable.

+1

+1

+1 Please fix this issue.

+1

+1

+1

We run into the same issue. Most of front-end apps we build need to consume multiple Rest webservices. Unable to opt out the security header is a big problem for us.

+1

+1

Try this guys on specific request object, alongside with headers, data and method:
transformRequest(data, headers) { delete headers.common.Authorization; return data; }

Try this, its solve my problem:

delete axios.defaults.headers.common["Authorization"]; // and create your own headers

@mukeshyadav That solution has been mentioned several times further up in this thread.

The point made is that this isn't necessarily the ideal solution. Imagining a scenario where you've added your own custom request/response interceptors to an Axios instance, but you want one specific request to not include headers used everywhere else, you'd have to delete the header(s) and re-add after the request is completed.

Conversely, wondering if there's a way you can, with relative ease, simply duplicate an Axios instance to use in these types of one-off cases.

+1

transformRequest: [(data, headers) => {
    delete headers.common.Authorization
    return data
}]

works for me

@aaronatmycujoo That seems like the sexiest solution here. Although, wondering if deleting the header like that removes it from an Axios instance further up the chain. May have to create a deep copy of headers or something.

I'll have to test that.

from what i can tell it doesn't. although there could be an edge case that i'm not triggering

@SepiaGroup you don't need to add headers in whole your requests... Do this:

axios.defaults.headers.common = {};
axios.defaults.headers.common.accept = ‘application/json’;

And in headers of request you'll only see ‘application/json’

+1 thanks @axelgenus ur solution worked

+1

@aaronatmycujoo FTW!!! His solution worked like a charm...ty!

Faced the same issue when trying to upload files to S3 (only allow one auth mechanism).
Tried the solution from @SepiaGroup but it also removes the auth header globally for all the following instances :(
@aaronatmycujoo This solution works perfectly for me! 🎉
Thank you guys for saving my day!

+1

+1

+1

axios.defaults.headers.common = {};
axios.defaults.headers.common.accept = ‘application/json’;

Works great for me!!!

Not sure if this is common knowledge, but there is a set of "forbidden headers", which cannot be deleted.

  • Accept-Charset
  • Accept-Encoding
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Connection
  • Content-Length
  • Cookie
  • Cookie2
  • Date
  • DNT
  • Expect
  • Host
  • Keep-Alive
  • Origin
  • Referer
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • Via

error

TypeError: Cannot convert undefined or null to object

delete axios.defaults.headers.cummon["Authorization"];

You have a typo @putu-eka-mulyana also I think this is the wrong place to report such an issue.

delete axios.defaults.headers.common["Authorization"];

+1, remove the charset from content-type

+1, remove Auth header for just one request, take in request config object without deleting explicitly, just by passing some value like undefined or null

+1, remove Auth header for just one request, take in request config object without deleting explicitly, just by passing some value like undefined or null

I have an OPTION request before my PUT request, so @aaronatmycujoo 's transformRequest solution worked for my OPTION request, but the Authorization header was still applied to my PUT request.

Ultimately i ended up making separate instances for auth vs public requests so my auth header was only applied to the auth instance.

// do not configure auth header
export const publicAxios = axios.create(...)

// configure auth header
export const authAxios = axios.create(...)

// no auth header present for public instance
publicAxios.put(...)

@rizen PR #1845 by @codeclown would allow unsetting headers by passing null. Would this solve the issue?

@rizen PR #1845 by @codeclown would allow unsetting headers by passing null. Would this solve the issue?

Yes

What a long journey. Hope #1845 get's merged asap.

transformRequest: [(data, headers) => {
    delete headers.common.Authorization
    return data
}]

From axios documentation:

> This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'

I am running into rather similar situation but with a GET request:

  1. GET http://www.saasserviceprovider.com/notpublicapi with header of Authorization: Bearer mytoken
  1. Redirects to AWS S3 endpoint. Redirect URL has a query string: X-Amz-Signature=blahblahblah appended.

  2. AWS S3 rejects call because two Authenication:

    • Header: Authorization bearer token
    • Query string: X-Amz-Signature=blahblahblah

Neither transformRequest, transformResponse, axios.interceptors.request, axios.interceptors.response appears to be able to allow me to inject myself into the process and temporarily remove the Authorization Header when hitting the redirection to AWS S3 - presumably if I could get in after a redirect I could do something to effect of delete headers.Authorization.

Same call with request api/postman/etc works.

"Workaround":

This is an ugly inefficent steaming POS... but but it "works™". Do I get VC funding now?

  let retry = false;
  await axios({
    method: 'get',
    url: "http://www.saasserviceprovider.com/notpublicapi",
    headers: {
      'Authorization': "Bearer mytoken",
    }
  })
  .then((r) => {
    //return successful
  })
  .catch ((e) => {
    if (e.request.res.responseUrl.match(/s3.amazonaws.com/)) {
      retry = e.request.res.responseUrl;
    } else {
          //log error
    }
  })

  //Retry
  if (retry) {
    await axios.get(retry)
    .then((r) => {
        //return successful
      }
    })
    .catch((e) => {
       //log error
    })
  }

Seriously though... has to be better way (within axios)

I am running into rather similar situation but with a GET request:

  1. GET http://www.saasserviceprovider.com/notpublicapi with header of Authorization: Bearer mytoken
  2. Redirects to AWS S3 endpoint. Redirect URL has a query string: X-Amz-Signature=blahblahblah appended.
  3. AWS S3 rejects call because two Authenication:
  • Header: Authorization bearer token
  • Query string: X-Amz-Signature=blahblahblah

Neither transformRequest, transformResponse, axios.interceptors.request, axios.interceptors.response appears to be able to allow me to inject myself into the process and temporarily remove the Authorization Header when hitting the redirection to AWS S3 - presumably if I could get in after a redirect I could do something to effect of delete headers.Authorization.

Same call with request api/postman/etc works.

Seriously though... has to be better way (within axios)

@iyerusad Did you find any better way than your workaround? I'm facing the same issue, and it's frustrating that I don't seem to be able to intercept the redirect and delete the Authorization header just for that follow-up / redirect request (to amazon in this case) 🤔

@iyerusad Did you find any better way than your workaround? I'm facing the same issue, and it's frustrating that I don't seem to be able to intercept the redirect and delete the Authorization header just for that follow-up / redirect request (to amazon in this case) 🤔

Not really - using option B. from below.

_The options I evaluated:_
A. Adopt alternative wrapper/client (e.g. fetch api? request? request seemed to work but is apparently deprecated). This might be cleanest option but means switching to another http client syntax.

B. Wrap my workaround into a function and use that function for requests that I know run into this issue - ugly seemingly less efficient but using this at the moment.

C. Hope I am an idiot and using axios wrong and there is saner workaround with axios.

D. Axios get fix/patch?

@mikhoq @iyerusad Would you mind to open a new issue to track your problem? Because it is different with the current one, which may have been fixed in #2844.

No problem - Opened #2855.

@mikhoq please add comment there if you have public repro endpoint.

So apparently transformRequest gets called for GET requests? I tried this and it worked, it only deleted the header for the current request.

transformRequest: [(data, headers) => {
    delete headers.common.Authorization
    return data
}]

But the docs say

// transformRequest allows changes to the request data before it is sent to the server
// This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'

Which made me think transformRequest wouldn't be called for GET requests, but it is. So what does this line actually mean?

"This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'"

Perhaps, "This is potentially only useful for ...." ....? It's misleading imo.

this works:
headers: {
'content-type': 'application/json',
'Authorization': null,
}

Tried setting { headers: { 'Content-Type' = null } } without success,
so to add to @axelgenus helpful comment, I had to go a bit further :

import Axios from 'axios'
const client = Axios.create({
  // ...
  transformRequest: [(data, headers) => {
    // add required "Content-Type" whenever body is defined
    if (data) headers['Content-Type'] = 'application/x-www-form-urlencoded'
    return data
  }],
})
// completely remove "Content-Type" from instance by default
delete client.defaults.headers.common['Content-Type']
delete client.defaults.headers.post['Content-Type']
delete client.defaults.headers.put['Content-Type']
delete client.defaults.headers.patch['Content-Type']
// ...

Use case was implementing requests layer for Bitstamp API V2 authentication method.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

c0debreaker picture c0debreaker  ·  3Comments

altruisticsoftware picture altruisticsoftware  ·  3Comments

ildella picture ildella  ·  3Comments

varmeh picture varmeh  ·  3Comments

Adman picture Adman  ·  3Comments