1

im trying to make a simple request to an API

  fetch('someurl').then((data) => console.log(data))

but im getting the classic No 'Access-Control-Allow-Origin' header is present on the requested resource.

how can I fix this on the client side? or is the only way to fix it for the API author to change it and add the correct response headers?

donut
  • 343
  • 2
  • 7
  • 15
  • The headers must be set by the *server* –  Aug 17 '18 at 13:46
  • 1
    You can't. The server is not allowing requests from other domains. – BenM Aug 17 '18 at 13:46
  • 1
    This is a security feature to prevent someone from using a resource that they shouldn't be using. If you have access to the server side code you need to implement CORS headers, if you don't then you can't/shouldn't be doing this. – Liam Aug 17 '18 at 13:48
  • See if the API supports a JSONP callback URL, that might be your only option. See also the accepted answer to the question [Use of success / jsonpCallback with ajax request](https://stackoverflow.com/questions/7167488/use-of-success-jsonpcallback-with-ajax-request) – Roy Scheffers Aug 17 '18 at 13:49
  • @RoyScheffers yes it does. so if i pass a callback into the url I might be able to retrieve the data? – donut Aug 17 '18 at 14:03
  • Yep, that's it. Give it a try. – Roy Scheffers Aug 17 '18 at 14:06
  • @RoyScheffers silly question but what should go in this callback? and does it just sit in the url like `&callback=something` ? – donut Aug 17 '18 at 14:10
  • No need to provide a specific name, let `$.ajax` take care of this. See my answer below. – Roy Scheffers Aug 17 '18 at 14:15

2 Answers2

1

To deepen you understand on CORS have a look at MDN's article on Cross-Origin Resource Sharing (CORS). It's pretty extensive.

Using jsonP you would be able to work around this when making simple GET requests. See also this older, short and sweet article that explains it in more detail. How JSONP Works.


The Wikipedia Definition of JSONP is as follows:

a communication technique used in JavaScript programs which run in Web browsers. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the same origin policy.

With that in mind, let look at the following example and make the request.

$(document).ready(function() {
  $.getJSON("https://jsonplaceholder.typicode.com/users?callback=?", function(json){
    console.log('getJSON call: ', json);
  });
})

FETCH does not support jsonp

After a bit of research, it does turn out that the Fetch API does not support jsonP requests. If you have a look at this jsFiddle example you'll see that the $.getJSON call returns data when used with the suffix ?callback=? while the 'fetch()' call fails and returns a CORS message. Open the console to see the result of both calls.

Your question in the comments

Also, do you know why fetch({ url : 'https://randomurl" }) would not get a CORS blockage but fetch('https://randomurl') would?

The first argument you provide to fetch is a string/URL, the second (optional) argument can be an options object {}. Because you provide an object as the first argument, that URL cannot be found. The reason why it doesn't give you a CORS blockage is because you provided an invalid URL, which returns a 404 status. Fetch deals with page cannot be found errors by returning a 200 OK status and in the JSON returned it will provide you with more info.

The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

Source: MDN docs

I hope this helped a bit in broadening your understanding of CORS and the how Fetch works.

Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
  • ok looks good but im using fetch. so i guess i just do `fetch('https://someurl.com/someapi/1.0/something?callback=successCallback').then((data) => console.log(data)` or something like that? – donut Aug 17 '18 at 14:17
  • also if after doing all that passing an object to fetch with the various keys you've done above in the xhr way and im still getting denied by CORS, what does that mean? – donut Aug 17 '18 at 14:37
  • CORS is short for Cross-Origin Resource Sharing. It'll help when you read up on it a little to understand making requests better. Check [Wikipedia](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing). I'm trying to tweak my example to work with fetch and an API that allows it. – Roy Scheffers Aug 17 '18 at 14:53
  • Are you using a public API that I could use to test? – Roy Scheffers Aug 17 '18 at 14:53
  • unfortunately not a public API but anyone but use any one and I'll get the idea i.e. https://jsonplaceholder.typicode.com/ – donut Aug 17 '18 at 15:36
  • also do you know why `fetch({ url : 'https://randomurl" })` would not get a CORS blockage but `fetch('https://randomurl')` would? – donut Aug 17 '18 at 15:38
  • I've updated my answer to include your question. I hope this helps. – Roy Scheffers Aug 17 '18 at 16:30
  • cool, I guess I can just use jsonp then – donut Aug 20 '18 at 06:38
0

You can find some workaounds in Why does my JavaScript get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when Postman does not? but you can't solve the problem from the client. It must be solved on server by setting correct headers that allow it...

José Matos
  • 569
  • 4
  • 13