1
votes

I am trying to send a cross domain request from a page on one domain to a PHP server on an other domain. Everything works fine without credentials (I need a session) but as soon as I add credentials, it doesn't work.

Here is the JS code :

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://phpserver.net',true);
xhr.withCredentials = true ;
xhr.onreadystatechange = function(e) {
    if (this.readyState == 4 && this.status == 200) {
        alert(this.responseText);
    }
}
xhr.send();

Please remember that it works without credentials. There is no alert. So I inspected the network with Firebug:

The request is correctly handled by the server, it's received with an HTTP code 200 but there is no content. I checked the headers :

HTTP/1.1 200 OK
Date: Fri, 14 Jun 2013 17:20:19 GMT
Server: Apache/2.4.2 (Win64) PHP/5.4.3
X-Powered-By: PHP/5.4.3
Access-Control-Allow-Origin: *
access-control-allow-credentials: true
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: key=441wqr3e4cf2456c763c1ea173aa06b5ad284e5f38; expires=Fri, 28-Jun-2013 17:20:19 GMT
key2=248fbaf41cdd698549fdddb341927885; expires=Fri, 28-Jun-2013 17:20:19 GMT
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

And finally my strangest discovery : The header "Content-Length" actually shows the real content length! If I add an echo "foo", the content-length increase by three and so on.

I looked trough lots of questions but this one is really tricky and I can't find any solution.

EDIT : I forgot to mention that this request works if instead of the xmlHttpRequest object I use a user-script and the GM_xhr function.

1
this could be a P3P issue, have you tried adding any P3P headers to the receiving PHP page?Samuel Cook
I'm not familiar with P3P so I searched what it is but I don't really see what's the relation with the problem and how to fix it.Demurgos

1 Answers

4
votes

When setting headerAccess-Control-Allow-Credentials to true, you cannot use a wildcard for header Access-Control-Allow-Origin. That is, a specific host must be specified.

Instead of:

Access-Control-Allow-Origin: *

Use:

Access-Control-Allow-Origin: http://safedomain.com

You can even set the Access-Control-Allow-Origin header to the Origin header received in the request. Not sure about PHP, but using the Java Servlets API:

String origin = request.getHeader("Origin");    
request.setHeader("Access-Control-Allow-Origin", origin);