Matt Fichman Matt Fichman - 4 months ago 13
Ajax Question

Why is the browser not setting cookies after an AJAX request returns?

I am making an ajax request using $.ajax. The response has the

Set-Cookie
header set (I've verified this in the Chrome dev tools). However, the browser does not set the cookie after receiving the response! When I navigate to another page within my domain, the cookie is not sent. (Note: I'm not doing any cross-domain ajax requests; the request is in the same domain as the document.)

What am I missing?

EDIT: Here is the code for my ajax request:

$.post('/user/login', JSON.stringify(data));


Here is the request, as shown by the Chrome dev tools:

Request URL:http://192.168.1.154:3000/user/login
Request Method:POST
Status Code:200 OK

Request Headers:
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:35
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
DNT:1
Host:192.168.1.154:3000
Origin:http://192.168.1.154:3000
Referer:http://192.168.1.154:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
X-Requested-With:XMLHttpRequest

Form Data:
{"UserId":"blah","Password":"blah"}:


Response:

Response Headers:
Content-Length:15
Content-Type:application/json; charset=UTF-8
Date:Sun, 16 Mar 2014 03:25:24 GMT
Set-Cookie:SessionId=MTM5NDk0MDMyNHxEdi1CQkFFQ180SUFBUkFCRUFBQVRfLUNBQUVHYzNSeWFXNW5EQXNBQ1ZObGMzTnBiMjVKWkFaemRISnBibWNNTGdBc1ZFcDNlU3RKVFdKSGIzQlNXRkkwVjJGNFJ6TlRVSHA0U0ZJd01XRktjMDF1Y1c1b2FGWXJORzV4V1QwPXwWf1tz-2Fy_Y4I6fypCzkMJyYxhgM3LjVHGAlKyrilRg==; HttpOnly

Answer

OK, so I finally figured out the problem. It turns out that setting the Path option is important when setting cookies from an ajax request. If you set Path=/, e.g.:

Set-Cookie:SessionId=foo; Path=/; HttpOnly

...then the browser will send the cookie when you navigate to a different page. Without setting Path, the browser uses the "default" path. Apparently the default path for ajax requests is different from the default path used when you navigate to a different page. I'm using Go/Martini, so on the server-side I do this:

session.Options(session.Options{HttpOnly: true, Path:"/"})

I guess Python/Ruby/etc. have a similar mechanism for setting Path.

See also: cookies problem in PHP and AJAX