从本地服务器访问API

时间:2014-07-13 01:22:45

标签: javascript ajax backbone.js

我正在尝试从本地Wamp服务器调用CTA API(http://www.transitchicago.com/developers/bustracker.aspx)。但是,当通过主干集合进行获取时,我得到:

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. 

系列:

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';
    },

 });

});

我知道这是一个常见的问题,但尚未找到简明的答案。

如何解决此问题? 的更新 添加了apiproxy但我得到了这个回复:

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

控制台:

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: (...)

1 个答案:

答案 0 :(得分:4)

你可以解决这个问题,但这并不是一个简单的例子,而是将这一行添加到你的JavaScript中,一切都会好的。"

您正在对抗每个网络浏览器中内置的same-origin security policy。 '产地'基本上意味着同一个网站&#39 ;;我在example.com上的JavaScript可以在example.com上访问它喜欢的任何内容,但它不允许从demonst.com,example.net或api.example.com读取任何内容。这有不同的起源。 Here's a table of what counts as the same origin

没有它,我可以写一个网页来窃取你所有的Gmail和私人Facebook照片。我的恶意JavaScript会向gmail.com和facebook.com发出网络请求,找到指向您电子邮件的链接。照片,加载数据,然后将其发送到我自己的服务器。

显然,有些网页旨在供其他人使用。例如,API通常希望允许访问其数据,以便人们可以构建Web应用程序。构建这些API的人可以使用Access-Control- headers来提供内容,告诉浏览器允许来自其他网站的请求。这称为CORS - 跨源资源共享。您收到该错误消息的原因是因为ctabustracker.com开发人员尚未添加任何CORS标头。因此,您无法从JavaScript访问其API。


那么解决方案是什么?你有两个选择:

  1. 通过电子邮件发送ctabustracker.com管理员并要求他们添加CORS标头以允许其他域访问。这对你来说是最不重要的工作,但你必须受知识,基础设施和工作的支配。及时开发团队。
  2. 编写自己的代理服务器。
  3. 同源政策只会阻碍您的JavaScript。你可以在服务器上做任何你喜欢的事情;最简单的是,你可以沿着以下几行创建一个apiproxy.php

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

    然后从您的JavaScript访问/apiproxy.php?method=getroutes,并通过标准查询字符串传递额外参数(例如,/apiproxy.php?method=test&foo=bar&cat=dog会产生对http://www.ctabustracker.com/bustime/api/v1/test?key=xx&foo=bar&cat=dog的请求)。现在,您的JavaScript正在向您自己的服务器发出请求,因此您不会对同源策略产生任何问题。

    当然,您可以根据需要使代理变得聪明。它可以缓存响应,将XM​​L转换为JSON,预取可能的下一个请求的结果,或者100个可能对您的应用有用的其他内容。