i am including JS on domain1 form domain2
<script type="text/javascript" src="http://www.domain2.com/script.js"></script>
that script doesn onload and on button click a JSONP request to domain2
$.getJSON( 'http://www.domain2.com/process?callback=?',
function(data){
if ( data ) processData( data );
}
);
and then displaying the data on domain1.
So here is my problem: The getJSON request doesnt send cookies to the domain2. The weirdest thing is that it does send the cookies half a day and the other half not. :-)
This is how the request looks like when it doesnt work:
Request details
GET /ajax/embed-user-library?detail=98&callback=jsonp1312398534998 HTTP/1.1
User-Agent: Opera/9.80 (Windows NT 6.1; U; en) Presto/2.9.168 Version/11.50
Host: www.floowie.com
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en,sk-SK;q=0.9,sk;q=0.8
Accept-Encoding: gzip, deflate
Referer: http://www.sokker.cz/en/test2
Connection: Keep-Alive
Response details
HTTP/1.1 200 OK
Date: Wed, 03 Aug 2011 19:06:51 GMT
Server: Apache/2.2.16 (Debian)
X-Powered-By: PHP/5.3.5-0.dotdeb.1
Set-Cookie: SESSID=64292b70dc28d7c6c9f13f70070353d8; path=/; domain=.floowie.com
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Content-Length: 34
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: application/json
And this when it works(nothing changed in the scripts):
Request details
GET /ajax/embed-user-library?detail=99&test=1&callback=jsonp1312398534999 HTTP/1.1
User-Agent: Opera/9.80 (Windows NT 6.1; U; en) Presto/2.9.168 Version/11.50
Host: test1.floowie.com
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: en,sk-SK;q=0.9,sk;q=0.8
Accept-Encoding: gzip, deflate
Referer: http://www.sokker.cz/en/test2
Cookie: __utma=254918925.1489796832.1301725317.1312260335.1312298033.44; __utmz=254918925.1312298033.44.11.utmcsr=sokker.cz|utmccn=(referral)|utmcmd=referral|utmcct=/en/test2; lang=en; FLWSESSID=ddd1bc696f83f5a70b5f0f3ae30b4691; __utma=121955676.1030804516.1282595153.1312390656.1312397285.194; __utmb=121955676.8.10.1312397285; __utmc=121955676; __utmz=121955676.1312397285.194.21.utmcsr=floowie.crmserver.cz|utmccn=(referral)|utmcmd=referral|utmcct=/index.php
Connection: Keep-Alive
Response details
HTTP/1.1 200 OK
Date: Wed, 03 Aug 2011 19:07:45 GMT
Server: Apache/2.2.16 (Debian)
X-Powered-By: PHP/5.3.5-0.dotdeb.1
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Content-Length: 20
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: application/json
Did someone see such a behaviour? Is it solvable?
Thank you
You have different hosts. In the first example the host is "Host: www.floowie.com". In the second it is "Host: test1.floowie.com".
I'm guessing that the cookies are originally set by 'test1.floowie.com' and you haven't specified that they should be available to '.floowie.com' (i.e. the whole domain and all subdomains).
Can you post the code that sets the cookies in the first place?
If you get this fixed, it should at least show consistent behaviour. However, IE will probably still not pass cookies across subdomains. That's what I'm wrestling with at the moment, which is how I can across your question.
You must properly implement CORS requests with credentials to send and receive cookies via Ajax. See developer.mozilla.org, specifically under the section titled "Requests with credentials."
First off, here is a simple CORS Ajax request with credentials, using jQuery 1.5.1+:
Note the
withCredentials
flag in the xhrFields. This flag tells the browser to send cookies with the request for the external domain, not the origin domain. In your case, cookies for www.domain2.com will be sent, and you will have access to them server-side.On the server-side, you need to add certain headers to the response:
Important: requests with credentials cannot set the Access-Control-Allow-Origin header to global (
Access-Control-Allow-Origin: *
). It must specify domains (Access-Control-Allow-Origin: www.domain1.com
).It's obviously better if you specify a domain for the Access-Control-Allow-Origin header. But if you don't know or care where the CORS request is coming from, you could use the
Origin
header from the request and simply set the Access-Control-Allow-Origin header of your response to that. In C#, this is how we did this:After doing all of this, cookies that you set server-side will be sent back with the response, and the browser will be able to properly handle them and insert them into the browser's cookie store for www.domain2.com. And any subsequent CORS requests you send will send these cookies in the request as well.
If you are sending a request other than with the GET, POST, or HEAD methods, you will need to implement Preflighted requests (see under section titled "Preflighted requests"):
Side-note about IE8 and IE9: The Ajax call above will fail in IE8 and 9. I included the JS file from MoonScript/jQuery-ajaxTransport-XDomainRequest on my page, and this automagically allowed CORS requests to work in those old IE versions. But sadly, the XDomainRequest object that MS created for IE8 and 9 does not allow cookies to be sent or received. (see this MSDN blog post for more information)
If you want to use AJAX petitions over different domains/subdomains you have to implement Cross Origin Requests.
References:
Examples:
Your server needs to send this headers:
You can return the Access-Control-Allow-Origin globally or set specifically dependent of your input Origin ($_SERVER['HTTP_ORIGIN']) request header. Also apply for Access-Control-Allow-Methods.
You must implement the OPTIONS petition. Before the first AJAX call, modern browsers call that URL with an OPTIONS method to retrieve the above headers.
Ok this is the first part, the second is with jQuery. Read very carefully this page: http://api.jquery.com/jQuery.ajax/
You will need to add some options to every AJAX call, you can do it globally:
Or specific:
This issue made me lose many hours... hope it helps.
Note that you won't need to set your cookie domain as ".floowie.com" if you want.