2

The exact error that I am struggling with is "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.".

I am trying to fetch JSON data using JavaScript from https://api.kraken.com/0/public/OHLC?pair=ETHEUR. I created a XMLHttpRequest object to do this, and specified GET as the type of request. This is supposedly a simple request, however the error says that a preflight request was sent. What is the reason for this behavior? That being said, to fix this error I tried to set a request header in which I specified '*' as the value for the Access-Control-Allow-Origin, yet I still get an error. I have looked through responses to similar questions as mine, but haven't been able to figure out how to solve the problem I am dealing with. This is probably due to still being very new to JavaScript. Either way, below is the code that I have written:

 var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR' var request = new XMLHttpRequest(); request.open('GET',requestURL,true); request.responseType = 'json'; request.onload = function(){ var data = request.response; console.log(data); } request.setRequestHeader('Access-Control-Allow-Origin','*'); request.send(); 
6
  • What is purpose of request.setRequestHeader('Access-Control-Allow-Origin','*')? Commented Aug 11, 2017 at 1:50
  • The error is telling me to supply an Access-Control-Allow-Origin, hence why I added that line of code. Clearly however it did not resolve the problem. Commented Aug 11, 2017 at 1:56
  • The error is notifying you that the requested resource does not have Access-Control-Allow-Origin header "No 'Access-Control-Allow-Origin' header is present on the requested resource." Are you trying to make an XMLHttpRequest() from file: protocol? Commented Aug 11, 2017 at 2:02
  • Yes, how would I go about doing that? (I am assuming that with file: protocol you mean the domain from which the request is being send is the path of the file I have written the above code in.) Commented Aug 11, 2017 at 2:10
  • At Chrome, Chromium browsers you can launch a new instance of the browser with --allow-file-access-from-files flag set see Read local XML with JS Commented Aug 11, 2017 at 2:13

1 Answer 1

4

In cases like this where the server you’re trying to make a cross-origin request to doesn’t send the Access-Control-Allow-Origin response header, your only option, if you want to make a request to that server from frontend JavaScript code running in a browser, is to use a CORS proxy. Otherwise, your browser won’t allow your frontend JavaScript code to access the response.

So, you can make your request succeed if you change your code to have something like this:

var proxyURL = 'https://cors-anywhere.herokuapp.com'; var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR'; var request = new XMLHttpRequest(); request.open('GET', proxyURL + '/' + requestURL, true); 

That sends the request through https://cors-anywhere.herokuapp.com, which forwards the request to https://api.kraken.com/0/public/OHLC?pair=ETHEUR and then receives the response. The https://cors-anywhere.herokuapp.com backend adds the Access-Control-Allow-Origin header to the response and passes that back to your requesting frontend code.

The browser will then allow your frontend code to access the response because that response with the Access-Control-Allow-Origin response header is what the browser sees.

You can also easily set up your own CORS proxy using https://github.com/Rob--W/cors-anywhere/

Note also that request.setRequestHeader('Access-Control-Allow-Origin','*') needs to be removed from the frontend code you are making the request with (as mentioned in comments above).

That’s because Access-Control-Allow-Origin is strictly a response header for servers to send in responses; sending it from the client side in a request will have no effect other than to trigger your browser to do an unnecessary CORS preflight OPTIONS request that will fail.

For details about what browsers do when you send cross-origin requests from frontend JavaScript code using XHR or the Fetch API or AJAX methods from JavaScript libraries—and details about what response headers must be received in order for browsers to allow frontend code to access the responses—see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.

var proxyURL = 'https://cors-anywhere.herokuapp.com'; var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR'; var request = new XMLHttpRequest(); request.open('GET', proxyURL + '/' + requestURL, true); request.responseType = 'json'; request.onload = function() { var data = request.response; document.querySelector('pre').textContent = JSON.stringify(data, null, 2); } request.send();
<pre></pre>

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for the detailed explanation, and a reference to where I can learn more about how cross origin requests work. That said, I tried implementing my request with a CORS proxy as you suggested. However doing so I am not able to retrieve the JSON data that resides on the requestURL, instead the request fetches the contents on the proxyURL.
Please try again with request.open('GET', 'https://cors-anywhere.herokuapp.com/https://api.kraken.com/0/public/OHLC?pair=ETHEUR', true), which will return exactly what you need. See the code snippet I added to the answer. (In the code in the initial answer I had left a trailing / in the proxyURL value that would have caused the request to not work as expected.)
what if https://cors-anywhere.herokuapp.com goes down or is unavailable. where do you get these proxies from?
@shorif2000 See stackoverflow.com/questions/47076743/…. If you have a Heroku account, you can spin up a CORS proxy of your own in literally just 2-3 minutes

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.