axios: Don't send default header

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.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 56
  • Comments: 74 (5 by maintainers)

Commits related to this issue

Most upvoted comments

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

works for me

I had the same problem but solved with

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

Yes. That did not work

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.

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

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

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

+1 Please fix this issue.

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})
}

@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’

error

TypeError: Cannot convert undefined or null to object

delete axios.defaults.headers.cummon[“Authorization”];

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.

Try this, its solve my problem:

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

+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.

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

@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();
  });
});

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"];

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

+1

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

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 😦

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

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

  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.

“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 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(...)

just keep the header in axios it works like charm. {```

  "Content-Type": "",

}

@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?

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

I tried every single suggestion from each post but none of them help. Axios still sending ‘Content-Type’ whenever I try to delete it. From React Native app I’m trying to upload file into AWS S3 via presigned url, and with Content-Type I get 403 error. I tried it with postman and without any headers, it uploads successfully, but I don’t understand why I can’t exclude Content-Type from http request.

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.

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.

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

Works great for me!!!

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

@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.