CORS enabled but still getting CORS error

12,472

You need to receive the following headers:

  • Access-Control-Allow-Origin: * (or whatever host you want to restrict to)
  • Access-Control-Allow-Methods: * (or whatever methods you want to restrict to)
  • Access-Control-Allow-Headers: Content-Type

Note the last one which is also important because you are setting Content-Type: application/json;charset=UTF-8. If you have any other custom headers you will need to add those too.

These are all to be done on the server though, your app doesn't need to do anything else.

Alternatively (if possible) you can opt to not use application/json at all and set your Content-Type to application/x-www-form-urlencoded, multipart/form-data, or text/plain and no preflight (OPTIONS) request will be done and it won't matter if CORS is enabled on the server or not.

Share:
12,472
Holly
Author by

Holly

I am a user who prefers to keep an air of mystery about myself, apparently.

Updated on June 05, 2022

Comments

  • Holly
    Holly almost 2 years

    I'm trying to get a JSON object from an API and the devs for the API said they just enabled CORS but I'm stilling getting the bellow error.

    XMLHttpRequest cannot load http://example.com/data/action/getGame/9788578457657. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://dev.our-domain.local' is therefore not allowed access.

    I'm using AngularJS to get the JSON in a Service with

    app.service("gameService", function ($http, $q)
    {
        function getGame(GameId) {
          var deferred = $q.defer()
          var url = 'http://example.com/data/action/getGame/' + gameId;
          // var url = 'https://jsonplaceholder.typicode.com/albums/' + gameId;  // THIS WORKS
          $http({
            method: 'GET',
            cache: true,
            url: url,
            headers: {  
               'Content-Type': 'application/json;charset=UTF-8'  
            }
          }).
          then(function(response) {
            //your code when success
            deferred.resolve(response);
            console.log('gameService HTTP CORS SUCCESS!');
          }, function(response) {
            //your code when fails
            console.log('gameService HTTP CORS ERROR!');
            // deferred.resolve('');        
            deferred.reject(response);
          });
          return deferred.promise;
        }
        this.getGame = getGame;
    })
    

    My AngularJS service works when I test it with jsonplaceholder which has CORS enabled.

    Am I missing something?

    The API devs said that two CORS-Headers are added to data.service responses but I don't see them. This is what I see on the headers when I curl down the JSON object.

    $ curl -X HEAD -i  http://example.com/data/action/getGame/9788578457657
    HTTP/1.1 200 OK
    Date: Wed, 14 Dec 2016 10:39:17 GMT
    Server: WildFly/8
    Expires: Wed, 14 Dec 2016 10:39:17 GMT
    X-Powered-By: Undertow/1
    X-dmg-elapsed-time: 20ms
    X-dmg-host-address: 1??.??.???.??
    Vary: Accept-Encoding,Origin
    X-dmg-generated-time: Wed, 14 Dec 2016 10:39:17 GMT
    Content-Type: application/json;charset=UTF-8
    Content-Language: en-
    X-dmg-node-name: defg_node_1
    X-Varnish-Bereq-Backend: real_backend_foo_bar_uk
    X-Varnish-Bereq-Retries: 0
    Last-Modified: Wed, 14 Dec 2016 10:39:17 GMT
    Cache-Control: public, max-age=300
    X-Varnish: 6876870
    Age: 0
    Via: 1.1 varnish-v4
    X-Varnish-Cache: MISS
    X-Varnish-Trimen: www.trimen.com
    X-Varnish-Served-By-Host: snarf.foo.uk
    X-Varnish-Served-By-IP: 100.100.10.80
    X-Varnish-Pool: http_pages
    X-Varnish-Req-Backend-Hint: dead
    X-Varnish-Req-Restarts: 0
    X-Varnish-Hash: /data/action/getGame/9788578457657
    X-Varnish-Backend-Ourself: varnish_server_snarf_foo_uk
    X-DMG-Version: 6.20.51.2358
    Accept-Ranges:  none
    Connection: keep-alive
    

    Is this what I should be seeing with CORS enabled or is there something more?

    Do I need to add more to my AngularJS Service to http get with Cors enabled, as add in more to:

    headers: {  
       'Content-Type': 'application/json;charset=UTF-8'  
    }
    

    UPDATE

    Passing Origin: in the header on my curl request as suggested by @t.niese

    $ curl -H "Origin: http://our-production-domain.com/" --verbose \
    >   http://example.com/data/action/getGame/9788578457657
    *   Trying 1?.???.??.???...
    * Connected to http://example.com/ (1?.???.??.???) port 80 (#0)
    > GET /data/action/getGame/9788578457657 HTTP/1.1
    > Host: http://example.com/
    > User-Agent: curl/7.43.0
    > Accept: */*
    > Origin: http://our-production-domain.com/
    > 
    < HTTP/1.1 200 OK
    < Date: Wed, 14 Dec 2016 11:05:24 GMT
    < Server: WildFly/8
    < Expires: Wed, 14 Dec 2016 11:05:24 GMT
    < X-Powered-By: Undertow/1
    < X-dmg-elapsed-time: 27ms
    < X-dmg-host-address: 1??.??.???.??
    < Vary: Accept-Encoding,Origin
    < X-dmg-generated-time: Wed, 14 Dec 2016 11:05:24 GMT
    < Content-Type: application/json;charset=UTF-8
    < Content-Language: en-
    < X-dmg-node-name: defg_node_1
    < X-Varnish-Bereq-Backend: real_backend_foo_bar_uk
    < X-Varnish-Bereq-Retries: 0
    < Last-Modified: Wed, 14 Dec 2016 11:05:24 GMT
    < Cache-Control: public, max-age=300
    < X-Varnish: 6876870
    < Age: 0
    < Via: 1.1 varnish-v4
    < X-Varnish-Cache: MISS
    < X-Varnish-Trimen: www.trimen.com
    < X-Varnish-Served-By-Host: snarf.foo.uk
    < X-Varnish-Served-By-IP: 100.100.10.80
    < X-Varnish-Pool: http_pages
    < X-Varnish-Req-Backend-Hint: dead
    < X-Varnish-Req-Restarts: 0
    < X-Varnish-Hash: /data/action/getGame/9788578457657
    < X-Varnish-Backend-Ourself: varnish_server_snarf_foo_uk
    < X-DMG-Version: 6.20.51.2358
    < Accept-Ranges:  none
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < 
    {
      "errorMessage" : null,
      "expiry" : "2016-12-14T11:05:24.379+0000",
      "data" : {
        // json object data here
      }
    * Connection #0 to host http://example.com/ left intact
    }
    

    and..

    $ curl -H "Origin: http://qa.our-qa-domain.com/" --verbose \
    >   http://example.com/data/action/getGame/9788578457657
    *   Trying 1?.???.??.???...
    * Connected to http://example.com/ (1?.???.??.???) port 80 (#0)
    > GET /data/action/getGame/9788578457657 HTTP/1.1
    > Host: http://example.com/
    > User-Agent: curl/7.43.0
    > Accept: */*
    > Origin: http://qa.our-qa-domain.com/
    > 
    < HTTP/1.1 200 OK
    < Date: Wed, 14 Dec 2016 11:06:11 GMT
    < Server: WildFly/8
    < Expires: Wed, 14 Dec 2016 11:06:11 GMT
    < X-Powered-By: Undertow/1
    < X-dmg-elapsed-time: 18ms
    < X-dmg-host-address: 1??.??.???.??
    < Vary: Accept-Encoding,Origin
    < X-dmg-generated-time: Wed, 14 Dec 2016 11:06:11 GMT
    < Content-Type: application/json;charset=UTF-8
    < Content-Language: en-
    < X-dmg-node-name: defg_node_1
    < X-Varnish-Bereq-Backend: real_backend_foo_bar_uk
    < X-Varnish-Bereq-Retries: 0
    < Last-Modified: Wed, 14 Dec 2016 11:06:11 GMT
    < Cache-Control: public, max-age=300
    < X-Varnish: 1343699
    < Age: 0
    < Via: 1.1 varnish-v4
    < X-Varnish-Cache: MISS
    < X-Varnish-Trimen: www.trimen.com
    < X-Varnish-Served-By-Host: snarf.foo.uk
    < X-Varnish-Served-By-IP: 100.100.10.80
    < X-Varnish-Pool: http_pages
    < X-Varnish-Req-Backend-Hint: dead
    < X-Varnish-Req-Restarts: 0
    < X-Varnish-Hash: /data/action/getGame/9788578457657
    < X-Varnish-Backend-Ourself: varnish_server_snarf_foo_uk
    < X-DMG-Version: 6.20.51.2358
    < Accept-Ranges:  none
    < Content-Length: 2988
    < Connection: keep-alive
    < 
    {
      "errorMessage" : null,
      "expiry" : "2016-12-14T11:06:11.927+0000",
      "data" : {
         // json data object here
      }
    * Connection #0 to host http://example.com/ left intact
    

    and..

    $ curl -H "Origin: http://dev.my-dev.local/" --verbose \
    >   http://example.com/data/action/getGame/9788578457657
    *   Trying 1?.???.??.???...
    * Connected to http://example.com/ (1?.???.??.???) port 80 (#0)
    > GET /data/action/getGame/9788578457657 HTTP/1.1
    > Host: http://example.com/
    > User-Agent: curl/7.43.0
    > Accept: */*
    > Origin: http://dev.my-dev.local/
    > 
    < HTTP/1.1 200 OK
    < Date: Wed, 14 Dec 2016 11:07:10 GMT
    < Server: WildFly/8
    < Expires: Wed, 14 Dec 2016 11:07:10 GMT
    < X-Powered-By: Undertow/1
    < X-dmg-elapsed-time: 28ms
    < X-dmg-host-address: 1??.??.???.??
    < Vary: Accept-Encoding,Origin
    < X-dmg-generated-time: Wed, 14 Dec 2016 11:07:10 GMT
    < Content-Type: application/json;charset=UTF-8
    < Content-Language: en-
    < X-dmg-node-name: defg_node_1
    < X-Varnish-Bereq-Backend: real_backend_foo_bar_uk
    < X-Varnish-Bereq-Retries: 0
    < Last-Modified: Wed, 14 Dec 2016 11:07:10 GMT
    < Cache-Control: public, max-age=300
    < X-Varnish: 6619151
    < Age: 0
    < Via: 1.1 varnish-v4
    < X-Varnish-Cache: MISS
    < X-Varnish-Trimen: www.trimen.com
    < X-Varnish-Served-By-Host: snarf.foo.uk
    < X-Varnish-Served-By-IP: 100.100.10.80
    < X-Varnish-Pool: http_pages
    < X-Varnish-Req-Backend-Hint: dead
    < X-Varnish-Req-Restarts: 0
    < X-Varnish-Hash: /data/action/getGame/9788578457657
    < X-Varnish-Backend-Ourself: varnish_server_snarf_foo_uk
    < X-DMG-Version: 6.20.51.2358
    < Accept-Ranges:  none
    < Content-Length: 2988
    < Connection: keep-alive
    < 
    {
      "errorMessage" : null,
      "expiry" : "2016-12-14T11:07:10.764+0000",
      "data" : {
            // JSON object data here
      }
    * Connection #0 to host http://example.com/ left intact
    }
    

    2nd UPDATE

    I disables same origin policy in Chrome and these are the headers to my JSON request from Chrome's network panel.

    GET data/action/getGame/9788578457657 HTTP/1.1
    Host: example.com
    Connection: keep-alive
    Pragma: no-cache
    Cache-Control: no-cache
    Accept: application/json, text/plain, */*
    Origin: http://dev.my-dev.local/
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36
    Referer: http://dev.my-dev.local//game/id-9788578457657
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8
    
    HTTP/1.1 200 OK
    Date: Wed, 14 Dec 2016 15:38:38 GMT
    Server: WildFly/8
    Expires: Wed, 14 Dec 2016 15:38:38 GMT
    X-Powered-By: Undertow/1
    X-dmg-elapsed-time: 25ms
    X-dmg-host-address: 172.16.0.70
    Vary: Accept-Encoding,Origin
    X-dmg-generated-time: Wed, 14 Dec 2016 15:38:38 GMT
    Content-Type: application/json;charset=UTF-8
    Content-Language: en-
    X-dmg-node-name: defg_node_1
    Content-Encoding: gzip
    Content-Length: 1109
    X-Varnish-Bereq-Backend: real_backend_foo_bar_uk
    X-Varnish-Bereq-Retries: 0
    Last-Modified: Wed, 14 Dec 2016 15:38:38 GMT
    Cache-Control: public, max-age=300
    X-Varnish: 6619151
    Age: 0
    Via: 1.1 varnish-v4
    X-Varnish-Cache: MISS
    X-Varnish-Trimen: www.trimen.com
    X-Varnish-Served-By-Host: snarf.foo.uk
    X-Varnish-Served-By-IP: 100.100.10.80
    X-Varnish-Pool: http_pages
    X-Varnish-Req-Backend-Hint: dead
    X-Varnish-Req-Restarts: 0
    X-Varnish-Hash: /data/action/getGame/9788578457657
    X-Varnish-Backend-Ourself: arnish_server_snarf_foo_uk
    X-DMG-Version: 6.20.51.2358
    Accept-Ranges: none
    Connection: keep-alive
    

    3rd UPDATE

    So after changing the http method to OPTIONS as in $http({ method: 'OPTIONS', ...

    I ge this error in the chrome consoler

    XMLHttpRequest cannot load http://example.com/data/action/getGame/9788578457657. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://dev.my-dev.local'' is therefore not allowed access. The response had HTTP status code 405.

    And these are the headers:

    OPTIONS /data/action/getGame/9788578457657 HTTP/1.1
    Host: example.com
    Connection: keep-alive
    Pragma: no-cache
    Cache-Control: no-cache
    Access-Control-Request-Method: OPTIONS
    Origin: http://dev.my-dev.local/
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36
    Access-Control-Request-Headers:
    Accept: */*
    Referer: http://dev.my-dev.local//game/id-9788578457657
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8
    
    HTTP/1.1 405 Method Not Allowed
    Date: Wed, 14 Dec 2016 16:52:03 GMT
    Server: Varnish
    X-Varnish: 6619151
    X-Varnish-Trimen: www.trimen.com
    X-Varnish-Served-By-Host: snarf.foo.uk
    X-Varnish-Served-By-IP: 100.100.10.80
    X-Varnish-Pool: 
    X-Varnish-Req-Backend-Hint: dead
    X-Varnish-Req-Restarts: 0
    X-DMG-Version: 6.20.51.2358
    Content-Type: text/html; charset=utf-8
    Retry-After: 5
    Content-Length: 49669
    Connection: keep-alive
    
  • Holly
    Holly over 7 years
    thanks so you're saying the correct CORS headers are not present on the API server and that they still need to be added? And the what I have on my AngularJS app should be sufficient to to get the JSON object if these headers were present?
  • ed'
    ed' over 7 years
    I've never used cURL to test this so I'm not sure. I don't see the headers there but at the same time I don't see any confirmation that your request is a preflight request, i.e. method OPTIONS, so its equally possible that your test request is wrong. I usually just check chrome dev tools inside the browser when making the actual request I want to work. You will see the preflight request in there, and if successful, another separate request after it
  • Holly
    Holly over 7 years
    How can I check if my request if preflight? I disabled the same origin policy in Chrome and got the headers to my JSON request from Chrome's network panel, I updated my question with the details. Does this help?
  • ed'
    ed' over 7 years
    send a request with Method: OPTIONS, said it like 3 times now :p method is request method, like POST, PUT, GET
  • Holly
    Holly over 7 years
    ok, got what you mean (I hope) and changed it to Method: OPTIONS. Updated the question with the headers, I still don't see the headers you listed in your question, so it would seem the API server is not configured correctly for CORs?
  • grandia
    grandia over 3 years
    the last one should be Access-Control-Allow-Headers, then the solution works well