【问题标题】:Access an API from local server从本地服务器访问 API
【发布时间】:2014-09-03 07:41:34
【问题描述】:

我正在尝试从本地 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: (...)

【问题讨论】:

  • 您尝试访问的服务器不允许从外部ip远程请求值传输
  • 您应该响应标头 Access-Control-Allow-Origin: * from the server to allow cross domain
  • 我猜这是因为您是从本地主机执行此操作,但问题是您请求的 URL 不允许您的请求

标签: javascript ajax backbone.js


【解决方案1】:

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

您遇到了每个网络浏览器中内置的same-origin security policy。 “起源”基本上是指“同一地点”;我在 example.com 上的 JavaScript 可以访问它喜欢在 example.com 上的任何内容,但不允许从 demo.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. 编写您自己的代理服务器。

同源策略只会阻碍您的 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 项其他可能对您的应用有用的事情。

【讨论】:

  • 很好的解释!我的 apiproxy.php 会放在我的目录中的什么位置?应用的根目录?
  • 如何在 apiproxy.php 中定义 getroutes 方法?还是来自我收藏中的网址?
  • 在我给出的示例中,apiproxy.php 文件将位于应用程序的根目录中。 getroutes 方法是通过query string 中的method 参数传入的。
  • 您的错误表明您的 PHP 没有运行。您应该确保它包含在 <?php 标记中。您应该能够在浏览器中访问 /apiproxy.php?method=getroutes,并检查它返回的内容(它应该看起来像 CTA 总线跟踪器 API 响应)。如果你不熟悉 PHP,那么the tutorial 值得一看。
  • 我已经更新了原始问题中的代理代码示例,因此它将任何额外的变量传递给 API。
猜你喜欢
  • 2018-10-21
  • 1970-01-01
  • 2021-09-17
  • 2015-06-21
  • 2016-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
相关资源
最近更新 更多