296

Can an AJAX response set a cookie? If not, what is my alternative solution? Should I set it with Javascript or something similar?

Martin.
  • 10,494
  • 3
  • 42
  • 68
Billworth Vandory
  • 5,003
  • 5
  • 29
  • 34
  • I am using node.js Express. I noticed that if you do that, you have to set the httpOnly field to false at the server side too apparently. – Chong Lip Phang Sep 02 '15 at 06:04

4 Answers4

317

According to the w3 spec section 4.6.3 for XMLHttpRequest a user agent should honor the Set-Cookie header. So the answer is yes you should be able to.

Quotation:

If the user agent supports HTTP State Management it should persist, discard and send cookies (as received in the Set-Cookie response header, and sent in the Cookie header) as applicable.

smwikipedia
  • 61,609
  • 92
  • 309
  • 482
Strelok
  • 50,229
  • 9
  • 102
  • 115
  • 1
    Does IE support the Set-Cookie header in responses, in case of XHR responses? – detj Oct 10 '12 at 14:07
  • As it should on a redirect, and it does not honor in some browsers. – Walter Macambira Sep 22 '15 at 14:52
  • 1
    For me using Chrome, headers received in ajax requests will automatically get applied to the client. – Alex Jun 20 '16 at 13:47
  • I found that if server side is setting back the response as gzip, the cookie doesn't get set. Is that supposed to be part of the spec or is that just an implementation issue? – juminoz May 24 '17 at 10:03
265

Yes, you can set cookie in the AJAX request in the server-side code just as you'd do for a normal request since the server cannot differentiate between a normal request or an AJAX request.

AJAX requests are just a special way of requesting to server, the server will need to respond back as in any HTTP request. In the response of the request you can add cookies.

this. __curious_geek
  • 42,787
  • 22
  • 113
  • 137
  • 47
    Keep in mind that whether the cookie will be honored by the HTTP agent is another story. – Franci Penov Jul 27 '10 at 04:48
  • 6
    @Franci: agreed. But I think the question only makes sense for http clients that support cookie. So all question-asker only wishes to know if cookies can be written in AJAX request that means his UA supports cookies :) – this. __curious_geek Jul 27 '10 at 04:52
  • 11
    `If the user agent supports HTTP State Management it should persist, discard and send cookies (as received in the Set-Cookie response header, and sent in the Cookie header) as applicable.` -- from http://www.w3.org/TR/XMLHttpRequest/ – smwikipedia Jan 06 '16 at 13:48
  • 1
    If the server can't differenciate between "normal" and ajax request, what is this api for in asp.net: 'this.Request.IsAjaxRequest' :) – Legends Apr 02 '16 at 11:10
  • 25
    This answers if the server can reply to an ajax request with a Set-Cookie header. And of course it can, but the question is whether that response will actually result in that the client reads and sets the cookie received in the ajax response, or if it has to be done manually. This is not an answer for that. – Alex Jun 20 '16 at 13:33
  • 2
    @Legends Ajax requests usually have the X-Requested-With header set to XMLHttpRequest, this is how they can be identified, but a request can be made without this header, if this happens it cannot be distinguished from a normal page load – T0m Aug 24 '17 at 14:47
96

For the record, be advised that all of the above is (still) true only if the AJAX call is made on the same domain. If you're looking into setting cookies on another domain using AJAX, you're opening a totally different can of worms. Reading cross-domain cookies does work, however (or at least the server serves them; whether your client's UA allows your code to access them is, again, a different topic; as of 2014 they do).

Bogdan Stăncescu
  • 5,320
  • 3
  • 24
  • 25
  • 27
    To send cross-domain cookies, you need to set the [withCredentials](https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control#Requests_with_credentials) flag – aeosynth Jan 28 '13 at 00:30
  • 8
    For cross-domain scenario, 3 things need to happen:- (1) Client needs to set `withCredentials=true` for the `xhr` object (2) Set `Access-Control-Allow-Credentials` both in the OPTIONS preflight request as well as the actual request (3) Set the cookie as needed – Kunal Jul 25 '17 at 21:16
6

Also check that your server isn't setting secure cookies on a non http request. Just found out that my ajax request was getting a php session with "secure" set. Because I was not on https it was not sending back the session cookie and my session was getting reset on each ajax request.

Phil
  • 1,996
  • 1
  • 19
  • 26
  • can you tell me , where i can check is ajax secure is set ? – Ziumper Jan 22 '19 at 11:58
  • 1
    It's not really ajax specific. Check for "Secure" in the Set-Cookie header response from the server if you are using insecure http:// – Phil Feb 06 '19 at 15:50