3

Would really appreciate anyone's help. I am relatively new to developing in React, using Mac OSX and Chrome as my browser. I have a small application that attempts to make an async GET request from Yelp Fusion's API using 'isomorphic-fetch', but receive the following error:

Fetch API cannot load https://api.yelp.com/v3/businesses/search?[remaining URL] Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I have done a lot of searching to see what responses to identical issues already exist, but I am left even more confused in how to tackle my problem with my relatively new knowledge to this kind of development environment. (Answers that seem particularly helpful are: Response to preflight request doesn't pass access control check and API Request with HTTP Authorization Header inside of componentDidMount, but I do not really understand how to actually implement those solutions with my environment. Any attempts I make seem incorrect and do not result in a change.).

As a side note: I have installed the Allow-Control-Allow-Origin: * extension on my Chrome browser, but I receive the same error - just a shortened, less elaborate description of it:

Fetch API cannot load https://api.yelp.com/v3/businesses/search?[remaining URL]. Response for preflight has invalid HTTP status code 500

The following is how I call the fetch in my code:

var options = (
    method: 'get',
    headers: new Headers({
        'Access-Control-Allow-Origin': '*',
        'Authorization': [my token]
        'Content-Type': 'application/json'
    })
}
return fetch(url, options);

Is this an issue due to the syntax of my header with Yelp Fusion's OAUTH2 token requirements, do I need to do something proxy-related, or is the reason because of something else? If proxy-related, currently I am running a fully client-driven application and do not use server-side code at all. Would this still be possible given my environment? Any guidance as to which direction I should go and clarification of my misconceptions would be greatly appreciated.

Again, thank you for your help for a growing developer.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
gpsugy
  • 1,199
  • 1
  • 11
  • 25

1 Answers1

5

This cause of the problem is that https://api.yelp.com/ doesn’t support CORS.

And there’s nothing you can in your own application code to fix that—no matter what you try, you can’t change the fact that https://api.yelp.com/ doesn’t support CORS.

Apparently the Yelp API does support JSONP though; see for example Yelp API Origin http://localhost:8888 is not allowed by Access-Control-Allow-Origin.

So using https://api.jquery.com/jquery.getjson/ or similar in your frontend code would allow you make requests to the Yelp API cross-origin from your frontend code.


A related issue in the GitHub issue tracker for the Yelp API examples repo confirms no CORS:

TL;DR: No CORS is not supported by api.yelp.com

And another related issue:

As I answered in #99 , we do not provide the CORS headers necessary to use clientside js to directly make requests to the api.

Both of the comments cited above are from a Yelp engineer.

So what the means is, there’s no way your frontend JavaScript code can make requests directly to Yelp API endpoints and get normal responses (as opposed to JSONP responses).

Specifically, because responses from the https://api.yelp.com/v3/businesses/search API endpoint don’t include the Access-Control-Allow-Origin response header, browsers will not allow your frontend JavaScript code to access those responses.

Also, because your request includes the Authorization and a Content-Type header with the value application/json, your browser does a CORS preflight options request before ever attempting the actual GET request you’re trying to send.

And that preflight is what’s specifically failing in this case. But any other request you make from the frontend code to that API endpoint would also fail—even if it didn’t trigger a preflight.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
  • thank you for your quick and thorough reply. If I am understanding you correctly, unless I implement server-side code into my application, I will not be able to make Yelp Fusion API calls? would using something like a node.js server allow me to do so, and is this a relatively simple API request or would it also require some kind of workaround? – gpsugy Jun 08 '17 at 21:01
  • @gpsugy Yep you won’t be able to make Yelp Fusion API calls unless you either implement server-side handling into your application, or else you set up a special CORS proxy, as explained in https://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource/42744707#42744707 – sideshowbarker Jun 08 '17 at 21:04
  • @gpsugy Apparently the Yelp API does support JSONP though; see for example https://stackoverflow.com/questions/3827614/yelp-api-origin-http-localhost8888-is-not-allowed-by-access-control-allow-ori So using https://api.jquery.com/jquery.getjson/ or similar in your frontend code would allow you make requests to the Yelp API cross-origin from your frontend code. I updated the answer to indicate that – sideshowbarker Jun 08 '17 at 21:18
  • That's great news! Looks like the link in the answer to the post you reference is a broken one, though (http://github.com/Yelp/yelp-api/blob/master/v1/googlemaps_example/businessSearch.html). Regardless, I see that the jsonp workaround for Yelp's API is done through jQuery. Would you or anyone know of a ReactJS alternative? Or perhaps I just need to include jQuery in my application and integrating it with my React code would be pretty seamless. – gpsugy Jun 09 '17 at 05:02
  • You don’t need jQuery or React or any other library/framework to handle JSONP. You can write up handling for it yourself pretty easily, by following examples at https://stackoverflow.com/questions/5943630/basic-example-of-using-ajax-with-jsonp/6879276#6879276 or some such – sideshowbarker Jun 09 '17 at 06:04
  • correct me if I'm wrong, but after working through many different methods attempting to receive JSONP from the Yelp Fusion API, it seems to not actually handle it. One of the many methods I have tried is implemented in the componentWillMount() method in my React component like so - even to the point of importing jquery, but receive a GET failure: `$.ajax({ url: 'https:api.yelp.com/businesses/search', dataType: 'jsonp', data: { term: 'Asian', latitude: [lat], longitude: [long] }, success: function(data) { console.log('received jsonp'); } });` – gpsugy Jun 09 '17 at 17:12
  • Post a different question if you’re having problems getting the JSONP – sideshowbarker Jun 09 '17 at 17:33