Ajax CORS 的替代方案

3
我有一个位于api.example.com域名下的REST API服务。我想在www.example.com中使用这个API来进行JavaScript AJAX请求。我使用CORS构建了我的jQuery AJAX请求(GET、POST、PUT和DELETE),在Firefox和Chrome上都可以正常工作。但是我在Opera上测试脚本时,什么也没加载出来。之后,我读了一些在线文章,并意识到CORS不能与Opera一起使用。那么,有哪些替代方法可以用来获取和放置Rest服务的数据呢?JSONp不行,因为我还需要其他HTTP动词(POST、PUT、DELETE)。在同一域名下创建一个“隧道”PHP脚本呢?但这会增加更多的网络流量和服务器负载。
Client -> WWW-Server -> API-Server
API-Server -> WWW-Server -> Client

替代

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

我很感谢所有跟我分享想法的人。


我认为你涵盖了所有的选项(CORS,JSONP,代理)。 - Jon
我没有检查,但是Opera 12支持CORS:http://dev.opera.com/articles/view/dom-access-control-using-cross-origin-resource-sharing/ - Andrew D.
实际上稳定的Opera版本是11.xx,不支持CORS。但我也想支持这个版本(当然还有用户),正在寻找一个解决方法。 - take
2个回答

3
你可以使用第三方工具进行隧道连接,例如YQL
Yahoo!查询语言是一种表达力强的类SQL语言,可以让你通过 Web 服务查询、筛选和连接数据。
YQL将作为一个中间人来对接从您的站点到您的API的调用。网络流量如下所示:
Client -> YQL -> API Server

我认为这看起来不错。

YQL 已经存在了相当长的时间。他们的免费配额非常有利,并且可用时间也相当不错:

  • 每个 IP 的限制:/v1/public/:每小时 2,000 次调用;/v1/yql/:每小时 20,000 次调用。

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

此外,配额不断增加,雅虎也提供一定的保证,如果他们决定关闭服务,他们会让它继续运行相当长的时间,以便您有时间迁移。今天有几个项目使用 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
}

这里还有一些关于优化YQL性能的好技巧


感谢您关心Opera用户!


我已经阅读了一些入门文章,YQL看起来很有趣,但不幸的是它与jquery.ajax非常不同。我有很多LOC AJAX和结果逻辑,并不想重写所有的代码,是否有一个jQuery插件或其他东西可以只切换请求?这样成功/错误、头部、部分都是相同的?(我需要发送身份验证头到我的API服务器) - take
YQL有一个叫做Tables的概念。这些是描述API的小型XML文档。您应该使用YQL控制台、YQL编辑器和YQL Lint进行操作。Linter特别有价值,因为您可以使用它测试自己的表格。您可以使用YQL安全地存储API密钥(在http://derek.io/blog/2010/how-to-secure-oauth-in-javascript/上了解更多信息)。 - Andrei Андрей Листочкин
1
关于重写您的 AJAX 调用。在 jQuery 中,您有一个非常好的钩子来处理这种情况:$.ajaxPrefiller(function (options) { /* 检查当前浏览器是否不支持跨域资源共享(CORS),如果是,则将 options.url 更改为 YQL 版本 */}) 把它放在任何跨域请求之前,然后您就可以放心使用了。 - Andrei Андрей Листочкин

0
最常见的解决方案是确实在您的服务器上使用代理脚本。
带宽很可能是可以忽略不计的——毕竟我们谈论的是小请求,而不是大型下载。 服务器负载也很小——您始终可以使用像node.js这样的异步和轻量级工具进一步减少负载。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接