此 Web API 未启用 CORS;我该如何使用它?

Posted

技术标签:

【中文标题】此 Web API 未启用 CORS;我该如何使用它?【英文标题】:This web API does not have CORS enabled; how can I use it? 【发布时间】:2014-10-08 12:54:21 【问题描述】:

我想从我正在制作的 Web 应用程序向 ChemSpider Web Api 发出 Ajax 请求 - 例如,使用 GetCompoundInfo 搜索功能。

此 API 以 XML 格式返回其数据。例如,搜索吡啶:

GetCompoundInfo?CSID=1020&token=redacted-security-token

结果

<?xml version="1.0" encoding="utf-8"?>
<CompoundInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.chemspider.com/">
  <CSID>1020</CSID>
  <InChI>InChI=1S/C5H5N/c1-2-4-6-5-3-1/h1-5H</InChI>
  <InChIKey>JUJWROOIHBZHMG-UHFFFAOYSA-N</InChIKey>
  <SMILES>C1=CC=NC=C1</SMILES>
</CompoundInfo>

看起来很简单。这是我的 Ajax 请求:

$.ajax(
  crossDomain: true,
  type: 'GET',
  url: "http://www.chemspider.com/Search.asmx/GetCompoundInfo",
  data: 
    "CSID": 1020,
    "token": "redacted-security-token",
  ,
  success: function(xmlstring, st, x) 
    success_stuff(xmlstring);
  ,
  failure: function(xmlstring, st, x) 
    failure_stuff(xmlstring);
  
);

但是,服务器似乎没有启用跨域资源共享。

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.chemspider.com/Search.asmx/CompoundInfo?CSID=1020&token=redacted-security-token. This can be fixed by moving the resource to the same domain or enabling CORS.

我不能使用 JSONP,因为数据是作为 XML 返回的,而不是 JSON。并且设置 crossDomain = true 似乎不起作用。

如何向此 Web API 发出简单的 GET 请求?

【问题讨论】:

【参考方案1】:

首先,与 ChemSpider 开发团队取得联系。询问他们是否会为 CORS 请求开放 API。他们可能很乐意提供帮助。

如果这不是一个选项,您需要设置一个代理,将调用直接作为 GET 请求而不是 ajax 请求进行。然后让您的 ajax 请求访问代理而不是 API 的域。

如果你是一个 python 程序员,uwsgi 和 urllib 让这变得非常简单。将以下代码另存为 ajaxproxy.py

请注意,以下代码仅用于演示其工作原理,并不解决安全问题。它有效地运行一个开放代理。除非您想以托管此服务器的名称完成各种有趣的业务,否则请勿将其按原样用于生产。

"""
Run with:
    uwsgi --http :9090 --wsgi-file ajaxproxy.py
"""
import urllib2

def application(env, start_response):
    # Get the resource url from the proxy's url & query string.
    resource_base_url = env['PATH_INFO'].split('/getresource/')[-1]
    if resource_query == '':
        resource_url = resource_base_url
    else:
        resource_url = '?'.format(resource_base_url, resource_query)

    # Get the resource.
    print('Getting resource: '.format(resource_url))
    resource_response = urllib2.urlopen(resource_url)
    resource_content = resource_response.read()

    # Return the resource to the requester.
    start_response('200 OK', [('Content-Type','text/html'), ('Access-Control-Allow-Origin', '*')])
    return [resource_content]

uwsgi 可以轻松安装

pip install wsgi

在您的 ajax 请求中会发生变化的只是 url:

$.ajax(
   url: 'http://127.0.0.1:9090/getresource/http://www.chemspider.com/Search.asmx/GetCompoundInfo',
...
);

当然,除了开发和测试之外,您还需要在公开可用的服务器上运行代理并将 127.0.0.1 更改为其地址。

【讨论】:

以上是关于此 Web API 未启用 CORS;我该如何使用它?的主要内容,如果未能解决你的问题,请参考以下文章

如何在webpack中使用跨域

启用 CORS 的 Web Api 2 facebook 身份验证

如何启用 CORS (JS + MVC Web API)

如何在 MEAN STACK Web 应用程序中启用 CORS?

如何在 WEB API 的 ASP.NET MVC 控制器级别中启用 CORS? [复制]

为 Web API 启用多个 CORS