简体   繁体   中英

Access an API from local server

I am trying to call the CTA API ( http://www.transitchicago.com/developers/bustracker.aspx ) from my local Wamp server. However, when doing the fetch via backbone collection I get:

XMLHttpRequest cannot load http://www.ctabustracker.com/bustime/api/v1/getroutes?key=xx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. 

collection:

define([
'models/route',
'core'
], function (Route) {

return Backbone.Collection.extend({

    initialize: function () {},

    model: Route,

    //url: function () {
    //  return 'http://www.ctabustracker.com/bustime/api/v1/getroutes?key=xx';
    //},

    url: function () {
        return '/apiproxy.php?method=getroutes';
    },

 });

});

I know this is a common issue but haven't found a concise answer yet.

How can I resolve this issue? Update Added the apiproxy but am getting this response:

Remote Address:127.0.0.1:80
Request URL:http://localhost/apiproxy.php?method=getroutes
Request Method:GET
Status Code:200 OK
Request Headersview parsed
GET /apiproxy.php?method=getroutes HTTP/1.1

console:

responseText: "$url = "http://www.ctabustracker.com/bustime/api/v1/{$_GET['method']}?   key=xx";
↵echo file_get_contents($url);

SyntaxError {stack: (...), message: "Unexpected token $"}
message: "Unexpected token $"
stack: (...)

You can solve this problem, but it's not a simple case of "add this line to your JavaScript and everything will be fine."

You're running up against the same-origin security policy built into every web browser. 'Origin' basically means 'the same site'; my JavaScript on example.com can access whatever it likes on example.com, but it's not allowed to read anything from demonstration.com, example.net, or api.example.com. That's got a different origin. Here's a table of what counts as the same origin .

Without it, I could write a web page that steals all your gmail and private Facebook photos. My malicious JavaScript would make web requests to gmail.com and facebook.com, find the links to your emails & photos, load that data too, and then send it off to my own server.

Obviously, some web pages are designed to be used by other people. APIs, for instance, generally want to allow access to their data so people can build web apps. The people building those APIs can serve their content with Access-Control- headers that tell browsers it's OK to allow requests from other sites. This is called CORS - Cross-Origin Resource Sharing. The reason you get that error message is because the ctabustracker.com developers haven't added any CORS headers. Thus, you can't access their API from your JavaScript.


So what's the solution? you have two options:

  1. Email the ctabustracker.com admins and ask them to add CORS headers to allow access from other domains. This is the least work for you, but you're at the mercy of the knowledge, infrastructure, & promptness of their development team.
  2. Write your own proxy server.

The same-origin policy is only standing in your way in your JavaScript. You can do whatever you like on the server; at its simplest, you could create an apiproxy.php along these lines:

$allExceptMethod = $_GET; // PHP arrays are copy-by-value
unset($allExceptMethod['method']);
$url = "http://www.ctabustracker.com/bustime/api/v1/{$_GET['method']}?key=xx&" . http_build_query($allExceptMethod);
echo file_get_contents($url);

And then access it from your JavaScript as /apiproxy.php?method=getroutes , and pass extra parameters in via a standard query string (for instance, /apiproxy.php?method=test&foo=bar&cat=dog results in a request to http://www.ctabustracker.com/bustime/api/v1/test?key=xx&foo=bar&cat=dog ). Now your JavaScript is making a request to your own server, so you won't have any problems with the same-origin policy.

You can, of course, make your proxy as smart as you like. It could cache responses, convert your XML to JSON, pre-fetch the results for likely next requests, or 100 other things that may be useful for your app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM