【问题标题】:Ajax CORS alternativesAjax CORS 替代品
【发布时间】:2012-05-21 18:51:49
【问题描述】:

我在域 api.example.com 上有一个 REST API 服务。并且想将此 api 用于我在 www.example.com 上的 javascript ajax 请求。

我使用 CORS 构建了我的 jQuery AJAX 请求(GET、POST、PUT 和 DELETE),并且在 firefox 和 chrome 上一切正常。我在 Opera 上测试了脚本,但没有加载任何内容。在此之后,我阅读了一些在线文章,不得不意识到 CORS 不适用于 Opera。

有哪些替代方法可以将数据获取和放置到 Rest 服务? JSONp 不起作用,因为我还需要其他 HTTP 动词(POST、PUT、DELETE)。

在同一个域上创建一个“隧道”php-Script?但是,我有更多的网络流量和服务器负载。

Client -> WWW-Server -> API-Server
API-Server -> WWW-Server -> Client

而不是

Client -> API-Server
API-Server -> Client

感谢与我分享的每一个创意。

【问题讨论】:

  • 我认为您涵盖了所有选项(CORS、JSONP、代理)。
  • 我不检查,但 Opera 12 支持 CORS:dev.opera.com/articles/view/…
  • Opera 的实际稳定版本是 11.xx,不支持 CORS。但我也想支持这个版本(当然还有用户)并寻找解决方法。

标签: php javascript ajax browser cors


【解决方案1】:

您可以使用第三方工具进行隧道传输,例如YQL

雅虎!查询语言是一种富有表现力的类 SQL 语言,可让您跨 Web 服务查询、过滤和连接数据。

YQL 将充当中间人,将来自您的站点的调用连接到您的 API。网络流量如下所示:

Client -> YQL -> API Server

我觉得不错。

YQL 已经存在了很长时间。他们的free quotas 很受欢迎,正常运行时间也很不错:

  • 每个 IP 限制:/v1/public/:每小时 2,000 次呼叫; /v1/yql/:每小时 20,000 次通话。

  • YQL 的性能正常运行时间目标超过 99.5%。

此外,配额不断增加,Yahoo!提供一定的保证,如果他们决定关闭服务,他们会保持它运行一段时间,这样你就有时间迁移。今天有几个项目使用 YQL(我知道有一个这样的服务 - TipTheWb.org

此外,我建议您检测给定浏览器是否支持 CORS 并仅在必要时回退到 YQL:

function browserSupportsCors() {
    if ("withCredentials" in new XMLHttpRequest())
        return true; // most browsers
    else if (typeof XDomainRequest == "object")
        return true; // IE8+
    else // Opera currently here, but they'll get better pretty soon :)
    return false;
}

或者如果你使用 jQuery,它有一个简洁的 support 方法。

if (!$.support.cors) {
    // YQL fallback
}

还有很棒的tips to tweak YQL performance


感谢您对 Opera 用户的关心!

【讨论】:

  • 我已经阅读了一些入门文章,YQL 看起来很有趣,但不幸的是,它与 jquery.ajax 也有很大不同。我有很多 LOC AJAX 和结果逻辑,不想重写所有代码,是否有一个 jQuery 插件或者我可以只切换请求的地方?那么成功/错误,标题,部分是否相同? (我有身份验证标头要发送到我的 api 服务器)
  • YQL 有这个表的概念。这些是描述您的 API 的小型 xml 文档。您应该使用 YQL 控制台、YQL 编辑器和 YQL Lint。 Linter 特别有价值,因为您可以用它测试自己的表。您可以使用 YQL 安全地存储您的 API 密钥(在derek.io/blog/2010/how-to-secure-oauth-in-javascript 上了解更多信息)。
  • 至于重写你的 AJAX 调用。在 jQuery 中,你有一个非常棒的钩子来处理这种情况:$.ajaxPrefiller(function (options) { /* check if current browser doesn't support CORS and change the options.url to YQL versions if that's the case */}) 在发出任何跨域请求之前放置一次,你就可以开始了。
【解决方案2】:

最常见的解决方案确实是在您的服务器上使用代理脚本。

带宽很可能可以忽略不计 - 我们说的是小请求,毕竟不是大下载。
而且服务器负载也很小——你总是可以使用一些异步和轻量级的东西,比如 node.js 来进一步减少负载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 2020-09-02
    • 1970-01-01
    • 2012-03-09
    • 2023-04-02
    • 2014-04-29
    • 2011-06-10
    • 2014-04-18
    相关资源
    最近更新 更多