jQuery - 如何消除跨域限制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11299438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery - How to remove cross domain limitation
提问by Tom
I am working on an web app for mobile, and jsonp is pretty cool for cross-domain request, but the API of server didn't support callback parameter. So I just can use json to fetch data from remote server.
我正在开发一个移动网络应用程序,jsonp 对于跨域请求非常酷,但是服务器的 API 不支持回调参数。所以我只能使用 json 从远程服务器获取数据。
I tried json in jQuery, seems it doesn't support cross-domain request. I tried raw ajax request function on safari, and it works good on cross-domain, so can I remove the limitation of cross-domain for json request in jQuery? (not jsonp, only json), and how to do it?
我在 jQuery 中尝试了 json,它似乎不支持跨域请求。我在 safari 上尝试了原始 ajax 请求功能,它在跨域上运行良好,那么我可以在 jQuery 中删除跨域对 json 请求的限制吗?(不是jsonp,只有json),以及怎么做?
Or is there any alternative simple ajax library (cross-web browser) and can do json on cross-domain request.
或者是否有任何替代的简单ajax库(跨网络浏览器)并且可以在跨域请求上执行json。
回答by Andrew Martinez
Same Origin Policy
同源政策
You are attempting to circumvent the Same Origin Policy. It is built into every browser and is not normally something you can or should want to disable/workaround/etc. It is a very important security contract between your site, the user, and the user's browser.
您正试图规避同源政策。它内置于每个浏览器中,通常不是您可以或应该想要禁用/解决方法/等的东西。它是您的站点、用户和用户浏览器之间非常重要的安全合同。
CORS (possible)
CORS(可能)
CORSallows your web server to tell browsers/clients that access to another domain is permissible. This is done by having the following HTTP header output by your web server
CORS允许您的 Web 服务器告诉浏览器/客户端访问另一个域是允许的。这是通过您的 Web 服务器输出以下 HTTP 标头来完成的
Access-Control-Allow-Origin: http://www.example.com
If you can not control your HTTP Headers, then you can not use CORS. Implementation of this is language/framework specific.
如果你不能控制你的 HTTP Headers,那么你就不能使用 CORS。这是特定于语言/框架的实现。
Please note that you should check to ensure browser compatibilityas IE8/9 had limited support. Also be aware that this is a potential attack vector. It allows responses from 3rd party sites to execute XSS attacks if you use the response data irresponsibly.
请注意,您应该检查以确保浏览器兼容性,因为 IE8/9 的支持有限。另请注意,这是一个潜在的攻击媒介。如果您不负责任地使用响应数据,它允许来自 3rd 方站点的响应执行 XSS 攻击。
JSONP(possible)
JSONP(可能)
JSONPis a clever way to pass and fetch data between servers by dynamically adding a script
tag with a src
atrribute equal to "yoururl.com?<your parameter data>"
to your page. It is the only legitimate way to accomplish such a feat without a web proxy (see below) or an applet (Flash/Java). However it does have its own security risks if you are not the provider of both ends of the request. Remember that JSONP allows the remote server to execute code within your context and you should be very careful who you give that power to.
JSONP是一种通过动态添加属性等于您的页面的script
标签 在服务器之间传递和获取数据的巧妙方法。这是在没有网络代理(见下文)或小程序(Flash/Java)的情况下完成这一壮举的唯一合法方式。但是,如果您不是请求两端的提供者,它确实有其自身的安全风险。请记住,JSONP 允许远程服务器在您的上下文中执行代码,您应该非常小心将这种权力授予谁。src
"yoururl.com?<your parameter data>"
"Vanilla" AJAX (not possible)
“香草”AJAX(不可能)
If you are not using the JSONP to fetch data then you are most likely attempting to use an AJAX request to fetch data. AJAX requests are also subjected to the Same Origin Policy. JavaScript libraries (e.g. jQuery, Prototype, Dojo, etc) can not circumvent this policy as base behavior for an Ajax Request. They can, however, support JSONP (which remember now, is not AJAX).
如果您没有使用 JSONP 来获取数据,那么您很可能会尝试使用 AJAX 请求来获取数据。AJAX 请求也受同源策略的约束。JavaScript 库(例如 jQuery、Prototype、Dojo 等)不能作为 Ajax 请求的基本行为来规避此策略。但是,它们可以支持 JSONP(现在记住了,它不是 AJAX)。
AJAX w/ Web Proxy (possible)
带有 Web 代理的 AJAX(可能)
If you do want to request data from another server, you can forward your request. Your main site's server will be acting as a proxy. You will need to make an AJAX request to your own server, that server side code will then make a request to the other domain and then send the response to your script via the AJAX calls response.
如果您确实想从另一台服务器请求数据,您可以转发您的请求。您的主站点的服务器将充当代理。您需要向您自己的服务器发出 AJAX 请求,然后该服务器端代码将向另一个域发出请求,然后通过 AJAX 调用响应将响应发送到您的脚本。
This is a common pattern and it is detailed here as the Web Proxy Patternand a pricture friendly Yahoo one here (but remember it's Yahoo specific, just take the general idea). It is however, server side language dependent. The overall implementation will be the same, however the code to do so will vary based on your server side language of choice (PHP, Ruby, Python, C, etc). Some languages will already have libraries/modules/etc to support such a pattern.
这是一种常见的模式,此处详细描述为Web 代理模式和 Yahoo 对图片友好的模式(但请记住它是 Yahoo 特定的,仅采用一般概念)。但是,它依赖于服务器端语言。整体实现将是相同的,但是执行此操作的代码将根据您选择的服务器端语言(PHP、Ruby、Python、C 等)而有所不同。一些语言已经有库/模块/等来支持这种模式。
Flash (possible, non-default)
Flash(可能,非默认)
Flash in its default state does not support cross domain requests. It can be turned on in Flash7+ with cross-domain policy files, but is highly suggested against. Your script would have to interface w/ a Flash API wich would make the requests and return the data to your JavaScript.
默认状态下的 Flash 不支持跨域请求。它可以在带有跨域策略文件的Flash7+ 中打开,但强烈建议不要使用。您的脚本必须与 Flash API 接口,以便发出请求并将数据返回给您的 JavaScript。
Java Applet (possible, non-default)
Java Applet(可能,非默认)
Java is also subjected to the same origin policy, but has a similar work around to Flash as described here on its release.
Java 也遵循同源策略,但与 Flash 的工作类似,如此处在其发行版中所述。
Various other "hacks"
各种其他“黑客”
There are other hacks out there, but they generally require you to control both ends or have an agreed upon standard for communication. For example the 'window.name' hack. I don't suggest most of these methods.
还有其他黑客,但它们通常要求您控制两端或有一个商定的通信标准。例如'window.name' hack。我不建议大多数这些方法。
Other Solutions
其他解决方案
Another question similar to this has been asked. It outlines a few other methods that I did not cover: Ways to circumvent the same-origin policy
另一个与此类似的问题已被问到。它概述了我没有涵盖的其他一些方法:绕过同源策略的方法
The Best Solutions
最佳解决方案
- CORS - if you trust the 3rd party
- Web Proxy - if you don't
- CORS - 如果您信任第 3 方
- 网络代理——如果你不这样做
A web proxy on your own domain can allow you to sanitize the data being retrieved, it offers your user's the most protection. However, if you do zero sanitation it is no more secure than any of the methods outlined here. If you do implement a web-proxy of some kind, make sure its requests are limited to and from the sites you wish. Else you will essentially be creating an open proxy, which could be abused by users if discovered and get you into legal trouble.
您自己域上的网络代理可以让您清理正在检索的数据,它为您的用户提供最大程度的保护。但是,如果您进行零卫生,它并不比此处概述的任何方法更安全。如果您确实实施了某种网络代理,请确保其请求仅限于您希望的站点。否则,您实际上将创建一个开放代理,如果发现该代理可能会被用户滥用并使您陷入法律麻烦。
回答by Claudiu
I had the same issue. Trying to get json from a server to wich I dind't had access (=> no JSONP).
我遇到过同样的问题。试图从服务器获取 json 到我没有访问权限(=> 没有 JSONP)。
I found http://benalman.com/projects/php-simple-proxy/Add the php proxy to your server and do the ajax call to this file. "Any GET parameters to be passed through to the remote URL resource must be urlencoded in this parameter."
我找到了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);
}
});
where proxy.php (the file from Ben Alman) is hosted in your domain
proxy.php(来自 Ben Alman 的文件)托管在您的域中
Alternative (which I found to be second best to this): http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
替代方案(我发现这是第二好的):http: //james.padolsey.com/javascript/cross-domain-requests-with-jquery/
回答by Clark T.
A rather tacky way of doing it would be what i've done below to enable cross site execution on a personal project
一种相当俗气的做法是我在下面所做的,以在个人项目上启用跨站点执行
please note this would be done on the receiving server not the sending one
请注意这将在接收服务器而不是发送服务器上完成
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 you want it to be a bit more secure you could do
如果你想让它更安全一点,你可以这样做
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');
}
Hope this helps it took me forever to figure it out lol.
希望这有助于我花了很长时间才弄明白,哈哈。