1

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...

Tejs
  • 40,736
  • 10
  • 68
  • 86
  • Try this: http://stackoverflow.com/questions/5584923/a-cors-post-request-works-from-plain-javascript-but-why-not-with-jquery – Tom Jul 10 '14 at 20:12
  • You may find useful this [post](http://stackoverflow.com/questions/24472352/external-css-styles-cant-be-accessed-in-google-chrome/24473183#24473183) as well; read the part related to CORS request. – hex494D49 Jul 10 '14 at 20:31
  • I'm using later than 1.5.2, and no `x-requested-with` header is sent in the request. Is the issue that there is no `Access-Control-Allow-Headers` in the response? – Tejs Jul 10 '14 at 20:31

2 Answers2

1

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:

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

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.

Mark At Ramp51
  • 5,343
  • 1
  • 25
  • 30
  • I see. Let me try removing the content type header or adding that accept-headers verb to see if that works... – Tejs Jul 10 '14 at 20:34
  • Ok, so now the response returns `Access-Control-Allow-Headers: content-type`, but Firefox still seems to be denying the request. – Tejs Jul 10 '14 at 20:46
  • You need to also respond with the allow credentials header: Access-Control-Allow-Credentials:true – Mark At Ramp51 Jul 10 '14 at 20:48
  • Response contains: `Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: content-type Access-Control-Allow-Credentials: true` - still no luck. – Tejs Jul 10 '14 at 21:06
  • Updated. It looks like the cross domain call is now working correctly, but Firefox keeps tanking the callbacks. jQuery arguments to the fail handler: {object}, {'error'}, {''} – Tejs Jul 10 '14 at 21:12
  • The response to the real GET request that occurs after the preflighted options request, needs to contain the same response headers that were returned in the preflight response. Give that a shot. – Mark At Ramp51 Jul 10 '14 at 21:16
  • Bingo, that did the trick. What a relief. Thanks for the assistance! – Tejs Jul 10 '14 at 21:27
0

Try setting

dataType:'html' 

(Where is the correct place to enable CORS?)

Community
  • 1
  • 1
ceremcem
  • 3,900
  • 4
  • 28
  • 66
  • This does not work. Specifying HTML only changes the response value to make me manually convert the response in IE to Json, and Firefox still reports inability to do the cross domain request. Any other potential ideas? I'm tearing my hair out at this point. – Tejs Jul 10 '14 at 20:22