2
votes

I'm hosting a website that has a number of different domain names pointing at it.

lets call the hosted website example.com and the url-forwarded domain names - example-x.com, example-y.com, example-z.com

When the url-forwarded domains are visited, cross domain requests are made back to the host site, example.com.

I'm currently making ajax GET requests to json files and receiving the following error;

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example-x.com' is therefore not allowed access.

Even though the preflight OPTIONS return a status of 200 and the GET method returns a status of 200.

OPTIONS;

enter image description here

GET enter image description here

I have set the following CORs headers on the host htaccess;

# <IfModule mod_headers.c>
   SetEnvIfNoCase Origin "https?://(www\.)?(example-x\.com|example-y\.com|example-z\.com)(:\d+)?$" ACAO=$0
   Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO
   Header set Access-Control-Allow-Methods "GET, PUT, POST, DELETE, OPTIONS"
  Header set Access-Control-Allow-Headers "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range"
Header set Access-Control-Allow-Credentials true
# </IfModule>

And i'm call GET using the following ajax request;

var createCORSRequest = function(method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) { 
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest !== "undefined") { 
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else { 
        xhr = null;
    }
    return xhr;
}; 

var url = 'http://example.com/data.json'; 
var xhr = createCORSRequest('GET', url);
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
xhr.setRequestHeader('Accept', 'application/json, text/javascript');  
xhr.onload = function() { console.log('success');}; 
xhr.onerror = function() { console.log('error'); }; 
xhr.send();

EDIT

Removing setRequestHeader("Content-Type", "application/json; charset=UTF-8") from the ajax request has removed the preflight requirement, however the CORs error still persists, the screenshot below shows the request / response of GET, its my guess that the correct htaccess headers have not been set on the RequestURL - http://example.com/cms/wp-content/uploads/2017/04/preloader_data.json

GET - WITHOUT OPTIONS PREFLIGHT enter image description here

2
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8"); — This is nonsense. You are making a GET request. There is no content to specify the content-type of. This is also why you have a preflight OPTIONS request in the first place.Quentin
@MartinChaov — Not a duplicate of that. The OP isn't trying to set Access-Control-Allow-Origin as a request header. They already have server side code which should set it as a response header. The question is why said code isn't working.Quentin
As Quentin says a GET request should not need to generate an OPTIONS request. Your client setup is likely wrong in the way mentioned.ADyson
Hi @Quentin, thanks for your reply.. its helped narrow down the issue. I've editted my question with the GET request/response i'm receiving now the preflight requirement is removed, i think the issue is htaccess / Header relatedCam

2 Answers

1
votes

You are trying to retrieve a json by a GET request. This should be a simple request, and it does not need to have a preflight request.

If you look at the requirements for a preflight request from MDN, you can see that setting Content-Type other than application/x-www-form-urlencoded, multipart/form-data or text/plain will cause this preflighted request.

If you look at the content-type from the RFC, it is a "SHOULD" for "a message containing a payload body". But your get request does not have a payload. As a result remove that header from your ajax call.

-3
votes

In the request from the client, you don't set proper headers:

xhr.setRequestHeader('Accept', 'application/json, text/javascript'); 
xhr.setRequestHeader('Access-Control-Allow-Headers', '*');

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example-x.com' is therefore not allowed access. -> xhr.setRequestHeader('Access-Control-Allow-Headers', '*');

I don't think we can answer better than this tutorial: https://www.html5rocks.com/en/tutorials/cors/

This website has information on how to setup your server to allow for CORS: https://enable-cors.org/server.html