从浏览器中运行的前端JavaScript代码调用Yelp API

时间:2017-06-08 20:13:20

标签: reactjs redux cors fetch-api isomorphic

非常感谢任何人的帮助。我在使用Mac OSX和Chrome作为浏览器时在React中开发相对较新。我有一个小应用程序尝试使用'isomorphic-fetch'从Yelp Fusion的API发出异步GET请求,但收到以下错误:

  

Fetch API无法加载https://api.yelp.com/v3/businesses/search [剩余网址] 对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源。因此,不允许原点“http://localhost:3000”访问。响应具有HTTP状态代码500.如果不透明响应满足您的需要,请将请求的模式设置为“no-cors”以获取禁用CORS的资源。

我已经做了很多搜索,看看已经存在对相同问题的回应,但是我对如何用我对这种开发环境的相对新知识来解决我的问题更加困惑。 (似乎特别有用的答案是:Response to preflight request doesn't pass access control checkAPI Request with HTTP Authorization Header inside of componentDidMount,但我真的不明白如何在我的环境中实际实现这些解决方案。我所做的任何尝试都显得不正确,并且不会导致更改。 )。

作为旁注:我在Chrome浏览器上安装了Allow-Control-Allow-Origin:*扩展程序,但我收到了同样的错误 - 只是缩短了,不那么精细的描述:

  

Fetch API无法加载https://api.yelp.com/v3/businesses/search [剩余网址] 。预检的响应具有无效的HTTP状态代码500

以下是我在代码中调用fetch的方法:

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

这是一个问题,因为我的标头的语法与Yelp Fusion的OAUTH2令牌要求有关,我是否需要做一些代理相关的事情,或者是因为其他事情的原因?如果代理 - 相关的,目前我正在运行一个完全由客户端驱动的应用程序,根本不使用服务器端代码。鉴于我的环境,这还有可能吗? 我将非常感谢任何关于我应该去哪个方向以及澄清我的误解的指导。

再次感谢您为不断壮大的开发人员提供的帮助。

1 个答案:

答案 0 :(得分:2)

问题的原因是https://api.yelp.com/不支持CORS。

在您自己的应用程序代码中没有任何东西可以解决这个问题 - 无论您尝试什么,都无法改变https://api.yelp.com/不支持CORS的事实。

显然Yelp API确实支持JSONP;例如,见Yelp API Origin http://localhost:8888 is not allowed by Access-Control-Allow-Origin

因此,在前端代码中使用https://api.jquery.com/jquery.getjson/或类似代码可以允许您从前端代码向Yelp API发出请求。

Yelp API示例repo的GitHub问题跟踪器中的related issue确认没有CORS:

  

TL; DR:api.yelp.com不支持CORS

another related issue

  

正如我在#99中回答的那样,我们不提供使用客户端js直接向api发出请求所必需的CORS头。

上面引用的两条评论都来自Yelp工程师。

那么意味着什么,你的前端JavaScript代码无法直接向Yelp API端点发出请求并获得正常响应(与JSONP响应相反)。

具体而言,由于来自https://api.yelp.com/v3/businesses/search API端点的响应不包含Access-Control-Allow-Origin响应标头,因此浏览器不允许您的前端JavaScript代码访问这些响应。

此外,由于您的请求包含AuthorizationContent-Type标头,其值为application/json,因此您的浏览器在尝试实际GET之前会执行CORS preflight options request请求你试图发送。

在这种情况下,预检是特别失败的。但是,从前端JavaScript代码到该API端点的任何其他请求也会失败 - 即使它没有触发预检。