我正在开发一个移动网络应用程序,jsonp 对于跨域请求非常酷,但是服务器的 API 不支持回调参数。所以我只能使用 json 从远程服务器获取数据。
我在 jQuery 中尝试了 json,似乎它不支持跨域请求。我在 safari 上尝试了 raw ajax 请求功能,它在跨域上运行良好,那么我可以消除 jQuery 中对 json 请求的跨域限制吗?(不是jsonp,只有json),怎么做?
或者是否有任何替代的简单 ajax 库(跨网络浏览器)并且可以对跨域请求执行 json。
我正在开发一个移动网络应用程序,jsonp 对于跨域请求非常酷,但是服务器的 API 不支持回调参数。所以我只能使用 json 从远程服务器获取数据。
我在 jQuery 中尝试了 json,似乎它不支持跨域请求。我在 safari 上尝试了 raw ajax 请求功能,它在跨域上运行良好,那么我可以消除 jQuery 中对 json 请求的跨域限制吗?(不是jsonp,只有json),怎么做?
或者是否有任何替代的简单 ajax 库(跨网络浏览器)并且可以对跨域请求执行 json。
同源政策
您正试图规避Same Origin Policy。它内置于每个浏览器中,通常不是您可以或不应该想要禁用/解决方法/等的东西。它是您的站点、用户和用户浏览器之间非常重要的安全契约。
CORS(可能)
CORS允许您的 Web 服务器告诉浏览器/客户端访问另一个域是允许的。这是通过您的 Web 服务器输出以下 HTTP 标头来完成的
Access-Control-Allow-Origin: http://www.example.com
如果你不能控制你的 HTTP 标头,那么你就不能使用 CORS。实现这一点是特定于语言/框架的。
请注意,您应该检查以确保浏览器兼容性,因为 IE8/9 支持有限。另请注意,这是一个潜在的攻击媒介。如果您不负责任地使用响应数据,它允许来自 3rd 方站点的响应执行 XSS 攻击。
JSONP(可能)
JSONP是一种在服务器之间传递和获取数据的巧妙方法,它通过动态添加一个属性等于您的页面的script
标签 。这是在没有 Web 代理(见下文)或小程序(Flash/Java)的情况下完成这一壮举的唯一合法方式。但是,如果您不是请求两端的提供者,它确实有其自身的安全风险。请记住,JSONP 允许远程服务器在您的上下文中执行代码,您应该非常小心将这种权力授予谁。src
"yoururl.com?<your parameter data>"
“香草”AJAX(不可能)
如果您没有使用 JSONP 来获取数据,那么您很可能会尝试使用 AJAX 请求来获取数据。AJAX 请求也受同源策略的约束。JavaScript 库(例如 jQuery、Prototype、Dojo 等)无法绕过此策略作为 Ajax 请求的基本行为。但是,它们可以支持 JSONP(现在记住,它不是 AJAX)。
带 Web 代理的 AJAX(可能)
如果您确实想从另一台服务器请求数据,您可以转发您的请求。您的主站点的服务器将充当代理。您需要向您自己的服务器发出 AJAX 请求,然后该服务器端代码将向另一个域发出请求,然后通过 AJAX 调用响应将响应发送到您的脚本。
这是一种常见的模式,在这里详细描述为Web 代理模式和对界面友好的 Yahoo模式(但请记住,它是 Yahoo 特定的,只接受一般概念)。但是,它取决于服务器端语言。整体实现将是相同的,但是执行此操作的代码将根据您选择的服务器端语言(PHP、Ruby、Python、C 等)而有所不同。一些语言已经有库/模块/等来支持这种模式。
Flash(可能,非默认)
默认状态下的 Flash 不支持跨域请求。它可以在 Flash7+ 中使用跨域策略文件打开,但强烈建议不要。您的脚本必须与 Flash API 交互,以便发出请求并将数据返回到您的 JavaScript。
Java Applet(可能,非默认)
Java 也受制于同源策略,但与 Flash 有类似的工作,如其发布中所述。
其他各种“黑客”
那里还有其他黑客,但它们通常要求您控制两端或有一个商定的通信标准。例如'window.name' hack。我不建议大多数这些方法。
其他解决方案
另一个类似的问题被问到了。它概述了我没有介绍的其他一些方法:绕过同源策略的方法
最佳解决方案
您自己域上的网络代理可以让您清理正在检索的数据,它为您的用户提供最大的保护。但是,如果您进行零卫生,它并不比此处概述的任何方法更安全。如果您确实实施了某种网络代理,请确保其请求仅限于您希望的站点。否则,您实际上将创建一个开放代理,如果发现它可能会被用户滥用并使您陷入法律麻烦。
我遇到过同样的问题。试图从服务器获取 json 到我无法访问的地方(=> 没有 JSONP)。
我找到http://benalman.com/projects/php-simple-proxy/将 php 代理添加到您的服务器并对这个文件进行 ajax 调用。“任何要传递到远程 URL 资源的 GET 参数都必须在此参数中进行 urlencoded。”
$.ajax({
type: 'GET',
url:'proxy.php?url=http://anyDomain.com?someid=thispage',
dataType: "json",
success: function(data){
// success_fn(data);
},
error: function(jqXHR, textStatus, errorThrown) {
// error_fn(jqXHR, textStatus, errorThrown);
}
});
proxy.php(来自 Ben Alman 的文件)托管在您的域中
替代方案(我发现这是第二好的):http: //james.padolsey.com/javascript/cross-domain-requests-with-jquery/
一种相当俗气的做法是我在下面所做的,以在个人项目上启用跨站点执行
请注意,这将在接收服务器而不是发送服务器上完成
if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE)
die('You shouldn\'t be here');
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type');
如果你想让它更安全一点,你可以这样做
if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE)
die('You shouldn\'t be here');
switch($_SERVER['HTTP_ORIGIN']){
case 'domain.com':
case 'whatever.com':
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type');
}
希望这会有所帮助,我花了很长时间才弄清楚哈哈。