Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS GET returns an empty response body in Firefox

From a RESTful Backbone application, I'm doing CORS requests from mydomain.com to myExtdomain.com.

I did set up CORS on my myExtdomain.com server, I'm responding to OPTIONS verb (any URL) with:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type

Status Code: HTTP/1.1 204 No Content

And to my API calls on myExtdomain.com with:

Access-Control-Allow-Origin: *
Content-Type: application/json

Status Code: HTTP/1.1 200 OK

I even desperately tried to respond to all my HTTP requests on myExtdomain.com with everything:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Content-Type: application/json

Status Code: HTTP/1.1 200 OK

The problem

  • Everything works fine in Chrome
  • In Firefox, my PUT requests work, but my GET requests "kinda fail"...

"Kinda fail" definition

  • The returned HTTP status code is 200 OK
  • But the response is empty (No Response Body/Size 0 KB).. It supposed to be some JSON.
  • But, for some reason, every once in 100 times, one GET request works

The boring details a.k.a "The Headers"

Responding to OPTIONS verb:

REQUEST HEADERS
-----------------
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0
Origin: http://mydomain.com
Host:   www.myExtdomain.com
Connection: keep-alive
Access-Control-Request-Method:  PUT
Access-Control-Request-Headers: content-type
Accept-Language:    en-US,en;q=0.5
Accept-Encoding:    gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

RESPONSE HEADERS
-----------------
X-Powered-By:   ASP.NET
Server: Microsoft-IIS/7.0
Date:   Fri, 15 Nov 2013 07:01:57 GMT
Content-Type:   text/html
Access-Control-Allow-Origin:    *
Access-Control-Allow-Methods:   POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers:   Content-Type

A PUT request:

REQUEST HEADERS
----------------
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0
Referer:    http://mydomain.com/account
Origin: http://mydomain.com
Host:   www.myExtdomain.com
Content-Type:   application/json; charset=UTF-8
Content-Length: 36
Connection: keep-alive
Accept-Language:    en-US,en;q=0.5
Accept-Encoding:    gzip, deflate
Accept: application/json, text/javascript, */*; q=0.01

RESPONSE HEADERS
----------------
X-Powered-By:   ASP.NET
Server: Microsoft-IIS/7.0
Date:   Fri, 15 Nov 2013 07:01:57 GMT
Content-Type:   application/json
Content-Length: 0
Access-Control-Allow-Origin:    *

BODY RESPONSE
--------------
_Some_Json_Here_

The magic GET request:

REQUEST HEADERS
----------------
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0
Referer:    http://mydomain.com/somepage
Origin: http://mydomain.com
Host:   www.myExtdomain.com
Connection: keep-alive
Accept-Language:    en-US,en;q=0.5
Accept-Encoding:    gzip, deflate
Accept: application/json, text/javascript, */*; q=0.01

RESPONSE HEADERS
----------------
Server: Microsoft-IIS/7.0
Last-Modified:  Fri, 15 Nov 2013 06:58:18 GMT
Date:   Fri, 15 Nov 2013 07:01:57 GMT
Content-Type:   application/json
Content-Length: 4041
Connection: keep-alive

RESPONSE BODY
--------------
Empty (0KB), it's supposed to be some JSON, that *SOMETIMES* (1/100) I get.. Magic.

Closing thoughts

  • As you can see the Response Headers of the magic GET request do not even include the CORS Headers I do set on myExtdomain.com
  • The PUT request on the other hand does include them..
  • Again, everything works just fine in Chrome, all the Response Headers are present, I get my JSON as expected, etc..
  • I spent a rather long time studying CORS (was not enough apparently), trying to break down what's needed/not needed and not copy/pasting random code
  • JSONP for GET requests is not an alternative for me
  • All my requests (any verb) are made from non-secure pages (not from https://)
  • I'm desperate..
like image 317
eightyfive Avatar asked Nov 15 '13 07:11

eightyfive


People also ask

How do you fix CORS missing Allow origin?

If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.

How do I fix my CORS policy?

To get rid of a CORS error, you can download a browser extension like CORS Unblock ↗. The extension appends Access-Control-Allow-Origin: * to every HTTP response when it is enabled. It can also add custom Access-Control-Allow-Origin and Access-Control-Allow-Methods headers to the responses.

How do I fix CORS error in HTML?

to fix the error, you need to enable CORS on the server. The client expects to see CORS headers sent back in order to allow the request. It might even send a preflight request to make sure that the headers are there. You can enable CORS server side for one, multiple, or all domains hitting your server.

What is Firefox CORS?

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.


2 Answers

Adding the Cache-Control: no-cache header to all my API calls Responses (on myExtdomain.com) solved my problem:

Access-Control-Allow-Origin: *
Content-Type: application/json
Cache-Control: no-cache

For some reason, Firefox was caching my API calls, and when cached, FF was not able to parse the JSON again.. Ending up in an empty response body or whatever error that was..

Now I remember this is not the first time I have to force no-cache with Firefox..

Again, everything was working fine with Chrome, Chrome does not need the Cache-Control: no-cache header.

If someone know about this difference between FF and Chrome (default settings??), I'd be curious to no more about it.

Hope this will save some time to somebody.

like image 116
eightyfive Avatar answered Oct 13 '22 09:10

eightyfive


For me, the solution was to add Access-Control-Allow-Credentials: true in response headers of server side: this is the symmetric of setting request.withCredentials = true; for a XMLHttpRequest object on client side.

like image 44
Emmanuel Avatar answered Oct 13 '22 09:10

Emmanuel