340

Does anyone know how to add or create a custom HTTP header using JavaScript or jQuery?

Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
Txugo
  • 4,606
  • 4
  • 30
  • 39

9 Answers9

622

There are several solutions depending on what you need...

If you want to add a custom header (or set of headers) to an individual request then just add the headers property:

// Request with custom header
$.ajax({
    url: 'foo/bar',
    headers: { 'x-my-custom-header': 'some value' }
});

If you want to add a default header (or set of headers) to every request then use $.ajaxSetup():

$.ajaxSetup({
    headers: { 'x-my-custom-header': 'some value' }
});

// Sends your custom header
$.ajax({ url: 'foo/bar' });

// Overwrites the default header with a new header
$.ajax({ url: 'foo/bar', headers: { 'x-some-other-header': 'some value' } });

If you want to add a header (or set of headers) to every request then use the beforeSend hook with $.ajaxSetup():

$.ajaxSetup({
    beforeSend: function(xhr) {
        xhr.setRequestHeader('x-my-custom-header', 'some value');
    }
});

// Sends your custom header
$.ajax({ url: 'foo/bar' });

// Sends both custom headers
$.ajax({ url: 'foo/bar', headers: { 'x-some-other-header': 'some value' } });

Edit (more info): One thing to be aware of is that with ajaxSetup you can only define one set of default headers and you can only define one beforeSend. If you call ajaxSetup multiple times, only the last set of headers will be sent and only the last before-send callback will execute.

Prestaul
  • 76,622
  • 10
  • 80
  • 84
  • What happens if I define a new `beforeSend` when doing a `$.ajax`? – Kostas Jul 09 '13 at 14:32
  • 3
    You can only define one `beforeSend` callback. If you call `$.ajaxSetup({ beforeSend: func... })` twice then the second callback will be the only one that fires. – Prestaul Jul 15 '13 at 15:29
  • 1
    Updated my answer to add more details about `ajaxSetup`. – Prestaul Jul 15 '13 at 15:34
  • Hi all, headers: { 'x-my-custom-header': 'some value' } doesn't work in IE 8. it works fine in firefox and chrome. I have to send custom headers using IE 8. Have you some idea to make it work? Thx – user1940268 Jan 30 '15 at 23:46
  • @user1940268 are you trying to do a cross domain (CORS) request or some other type of custom header? I've certainly used all of these techniques in IE8 and am certain they work. The one exception is xDomain requests where you need another technique in IE8. – Prestaul Feb 01 '15 at 00:49
  • @Prestaul thx for your reply. My ajax request is in the same domain. $(document).ready(function() { $.ajax({ url: url, type: "POST", headers: { 'x-my-custom-header': 'some value' } }); }); – user1940268 Feb 01 '15 at 10:54
  • @user1940268, I think there must be something else going on outside of the posted code (possibly server-side when trying to read the headers). your ajax call looks right and I don't think I'm going to be able to help you here. – Prestaul Feb 09 '15 at 22:05
  • 2
    Looks like it doesn't work with CORS Request (every browser). Is there a work around ? – svassr May 13 '15 at 13:54
  • found my solution here http://stackoverflow.com/questions/8685678/cors-how-do-preflight-an-httprequest – svassr May 13 '15 at 14:15
  • @svassr CORS has different requirements and, as you found out, beyond a few (very basic) headers, any additional will have to be whitelisted via the `Access-Control-Request-Headers` header. – Prestaul May 14 '15 at 15:22
  • For my case, I wanted the http header `accept` value to be strictly just `text/plain`. ajax's `accepts` behavior really tripped me up. It kept adding an extra \*/\* to the end, after my `text/plain`. Sigh. Specifying the `headers` works better. – Kevin Lee Dec 08 '16 at 15:51
  • I get this error: Response to preflight request doesn't pass access control check – Si8 Jan 25 '17 at 14:54
  • 1
    @Si8, that looks like a cross domain issue to me. You can't make a request from one domain to another. Try looking into CORS and see if that helps. – Prestaul Mar 28 '17 at 20:21
  • These don't really work. I tried them and they change my request to `options` from `post` or `get` – mrid Oct 10 '20 at 03:41
55

Or, if you want to send the custom header for every future request, then you could use the following:

$.ajaxSetup({
    headers: { "CustomHeader": "myValue" }
});

This way every future ajax request will contain the custom header, unless explicitly overridden by the options of the request. You can find more info on ajaxSetup here

Szilard Muzsi
  • 1,861
  • 2
  • 16
  • 20
  • 1
    Where i really want to accomplish this, this doesn't seem to actually work. – Trip Jan 25 '13 at 17:33
  • 1
    Well you should make sure that the ajaxSetup is called before the actual ajax call. I don't know of any other reason why this wouldn't work :) – Szilard Muzsi Jan 30 '13 at 16:03
25

You can also do this without using jQuery. Override XMLHttpRequest's send method and add the header there:

XMLHttpRequest.prototype.realSend = XMLHttpRequest.prototype.send;
var newSend = function(vData) {
    this.setRequestHeader('x-my-custom-header', 'some value');
    this.realSend(vData);
};
XMLHttpRequest.prototype.send = newSend;
Roland T.
  • 791
  • 8
  • 16
21

Assuming JQuery ajax, you can add custom headers like -

$.ajax({
  url: url,
  beforeSend: function(xhr) {
    xhr.setRequestHeader("custom_header", "value");
  },
  success: function(data) {
  }
});
Jayendra
  • 50,361
  • 4
  • 75
  • 89
19

Here's an example using XHR2:

function xhrToSend(){
    // Attempt to creat the XHR2 object
    var xhr;
    try{
        xhr = new XMLHttpRequest();
    }catch (e){
        try{
            xhr = new XDomainRequest();
        } catch (e){
            try{
                xhr = new ActiveXObject('Msxml2.XMLHTTP');
            }catch (e){
                try{
                    xhr = new ActiveXObject('Microsoft.XMLHTTP');
                }catch (e){
                    statusField('\nYour browser is not' + 
                        ' compatible with XHR2');                           
                }
            }
        }
    }
    xhr.open('POST', 'startStopResume.aspx', true);
    xhr.setRequestHeader("chunk", numberOfBLObsSent + 1);
    xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
            receivedChunks++;
        }
    };
    xhr.send(chunk);
    numberOfBLObsSent++;
}; 

Hope that helps.

If you create your object, you can use the setRequestHeader function to assign a name, and a value before you send the request.

Misha Reyzlin
  • 12,998
  • 4
  • 51
  • 62
James
  • 519
  • 2
  • 6
  • 3
    While this may have been correct in 2011, it's generally a good idea to not reinvent the wheel, and instead use an AJAX library like Zepto or jQuery. – Dan Dascalescu Oct 11 '14 at 05:26
  • 4
    Unless you are trying to add a header to an existing XHR2 call and don't want to start rewriting it all to use jQuery just for that... At which point, @gryzzly has the only viable answer. – roryhewitt Nov 18 '14 at 23:41
  • @AliGajani The problem is that certain applications or libraries (like THREE.js) don't use `$.ajax*` functions b/c they don't depend on jQuery and instead use XHR so this is the only valid option in those cases. – Coburn Apr 18 '17 at 03:39
  • 1
    @AliGajani Additionally, it's not just the network load time but the parsing time of the library. Plus, if you are not careful with what dependencies you add, you can quickly get a project with too many dependencies – Oztaco - Reinstate Monica C. Nov 08 '17 at 20:03
16

You should avoid the usage of $.ajaxSetup() as described in the docs. Use the following instead:

$(document).ajaxSend(function(event, jqXHR, ajaxOptions) {
    jqXHR.setRequestHeader('my-custom-header', 'my-value');
});
Stefan D.
  • 247
  • 4
  • 8
6

Assuming that you mean "When using ajax" and "An HTTP Request header", then use the headers property in the object you pass to ajax()

headers(added 1.5)

Default: {}

A map of additional header key/value pairs to send along with the request. This setting is set before the beforeSend function is called; therefore, any values in the headers setting can be overwritten from within the beforeSend function.

http://api.jquery.com/jQuery.ajax/

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
3

"setRequestHeader" method of XMLHttpRequest object should be used

http://help.dottoro.com/ljhcrlbv.php

4esn0k
  • 7,609
  • 6
  • 29
  • 38
0

You can use js fetch

async function send(url,data) {
  let r= await fetch(url, {
        method: "POST", 
        headers: {
          "My-header": "abc"  
        },
        body: JSON.stringify(data), 
  })
  return await r.json()
}

// Example usage

let url='https://server.test-cors.org/server?enable=true&status=200&methods=POST&headers=my-header';

async function run() 
{
 let jsonObj = await send(url,{ some: 'testdata' });
 console.log(jsonObj[0].request.httpMethod + ' was send - open chrome console > network to see it');
}

run();
Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241