我正在尝试从本地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: (...)
答案 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。
那么解决方案是什么?你有两个选择:
同源政策只会阻碍您的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正在向您自己的服务器发出请求,因此您不会对同源策略产生任何问题。
当然,您可以根据需要使代理变得聪明。它可以缓存响应,将XML转换为JSON,预取可能的下一个请求的结果,或者100个可能对您的应用有用的其他内容。