I'm trying to get a cross domain request to work. The relevant code is as follows:
var promise = $.ajax({
type: 'GET',
url: registerUrl,
dataType: 'json',
cache: false,
crossDomain: true,
xhrFields: { withCredentials: true },
contentType: 'application/json'
});
I control the calling and receiving server, and this is response that I am getting:
Raw request (courtesy of Fiddler):
OPTIONS http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405022169353 HTTP/1.1
Host: localhost:5080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:53054
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive
Raw response:
HTTP/1.1 200 OK
Date: Thu, 10 Jul 2014 19:56:11 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Content-Length: 0
Server: Jetty(8.1.4.v20120524)
Now, my understanding is that Allow-Origin: *
for this preflight should be enough for Firefox / Chrome to let the request continue. Oddly enough, IE does no preflight for this request, and it works (despite throwing up a warning that it is not following the CORS specification).
Am I missing something here? I've tried setting every value on the ajax request I can think of, and the server looks to be responding with the appropriate response to the OPTIONS request.
The specific error message from firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405022169353. This can be fixed by moving the resource to the same domain or enabling CORS.
What am I doing wrong? What can be changed to fix this?
EDIT: New request / response fields:
OPTIONS http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405026511996 HTTP/1.1
Host: localhost:5080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:53054
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive
Response:
HTTP/1.1 200 OK
Date: Thu, 10 Jul 2014 21:08:38 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Credentials: true
Content-Length: 0
Server: Jetty(8.1.4.v20120524)
Now, fiddler also records the actual request:
GET http://localhost:5080/mportal/registerChat?gsid=abcde&ul=100,200&_=1405026511996 HTTP/1.1
Host: localhost:5080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Referer: http://localhost:53054/
Origin: http://localhost:53054
Connection: keep-alive
And the response:
HTTP/1.1 200 OK
Date: Thu, 10 Jul 2014 21:08:38 GMT
Content-Type: application/json;charset=ISO-8859-1
Content-Length: 175
Server: Jetty(8.1.4.v20120524)
{"status":true,"host":"<myServerName>","port":1935,"liveHost":"<myServerName>","livePort":5080,"gsid":"abcde","connCount":2,"maxConns":25000,"version":"1.0"}
However, firefox seems to be blocking the request and thus the ajax call always hits my fail handler. This seems odd...
It looks like your request is asking for permission to send a content-type request header, and it requires permission to send credentials.
Your request headers appear to be correct as far as I can tell. However your response should contain two more headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type
Here is an example of a preflight request from another site I've worked on, and the preflight response:
Here is the preflight option requestion headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, applicationname
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Cookie:*sanitized cookie data*
Host:sanitized.domain.com
Origin:https://sanitized.domain.com
Pragma:no-cache
Referer:https://sanitized.domain.com/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Subsequently here is the preflight response headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:applicationname
Access-Control-Allow-Origin:https://sanitized.domain.com
Cache-Control:no-cache
Connection:keep-alive
Content-Length:0
Date:Thu, 10 Jul 2014 20:19:25 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Notice the addition of the Access-Control-Allow-Credentials, and Access-Control-Allow-Headers headers. Also notice my request sent "accept" in the Access-Control-Request-Headers header, and the response didn't contain "accept". This is because "accept" is considered a simple header as defined here: http://www.w3.org/TR/cors/#simple-header. Additionally content-type qualifies as a simple header only when it's value is one of the following:
In your case since the content type is application/json, you would need a response header that contains "content-type", as displayed above.
UPDATE: Your request and response that occur after the preflighted request should contain the same CORS headers to prevent the browser from rejecting the request and/or response. At a bare minimum you'll want the response to contain the Access-Control-Allow-Credentials and the Access-Control-Allow-Origin headers.