This web API does not have CORS enabled; how can I use it?

≡放荡痞女 提交于 2019-12-13 05:18:29

问题


I want to make an Ajax request to the ChemSpider Web Api from a web application that I'm making -- for example, using the GetCompoundInfo search function.

This API returns its data in XML format. For example, a search for pyridine:

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

results in

<?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>

Seemed simple enough. This was my Ajax request:

$.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);
  }
});

However, the server doesn't seem to have Cross-Origin-Resource-Sharing enabled.

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.

I can't use JSONP, because the data is returned as XML, not JSON. And setting crossDomain = true doesn't seem to be working.

How can I make a simple GET request to this web API?


回答1:


First, get in touch with the ChemSpider development team. Ask them if they'd open the API up for CORS requests. They might be happy to help.

If that isn't an option, you'll need to set up a proxy which makes the calls directly as a GET request rather than an ajax request. Then make your ajax requests hit the proxy instead of the API's domain.

If you're a python programmer, uwsgi & urllib make this pretty simple. Save the following code as ajaxproxy.py.

Please note the following code is only to demonstrate how this works and doesn't address security issues. It effectively runs an open proxy. Don't use this as-is for production unless you want all sorts of funny business done in the name of the server you host this on.

"""
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 can be easily installed with

pip install wsgi

All that would change in your ajax request would be the url:

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

Of course for anything besides development & testing you'll need to run the proxy on a publicly-available server and change 127.0.0.1 to its address.



来源:https://stackoverflow.com/questions/25315383/this-web-api-does-not-have-cors-enabled-how-can-i-use-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!