jQuery AJAX 跨域
这里有两个页面,test.php 和 testserver.php。
test.php
<script src="scripts/jq.js" type="text/javascript"></script>
<script>
$(function() {
$.ajax({url:"testserver.php",
success:function() {
alert("Success");
},
error:function() {
alert("Error");
},
dataType:"json",
type:"get"
}
)})
</script>
testserver.php
<?php
$arr = array("element1",
"element2",
array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>
现在我的问题是:当这两个文件位于同一服务器(本地主机或 Web 服务器)上时,它可以工作并且 alert( “成功”)
被调用;如果它位于不同的服务器上,即 Web 服务器上的 testserver.php 和本地主机上的 test.php,则它不起作用,并且 alert("Error")
正在执行。即使 AJAX 内的 URL 更改为 http://domain.example/path/to/file/testserver.php
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
使用 JSONP。
jQuery:
PHP:
回声可能是错误的,我已经有一段时间没有使用 php 了。在任何情况下,您都需要输出
callbackName('jsonString')
注意引号。 jQuery 将传递它自己的回调名称,因此您需要从 GET 参数中获取该名称。正如 Stefan Kendall 发布的那样, $.getJSON() 是一种简写方法,但是你需要将
'callback=?'
附加到 url 作为 GET 参数(是的,值为 ?,jQuery 用它自己生成的回调方法替换它)。Use JSONP.
jQuery:
PHP:
The echo might be wrong, it's been a while since I've used php. In any case you need to output
callbackName('jsonString')
notice the quotes. jQuery will pass its own callback name, so you need to get that from the GET params.And as Stefan Kendall posted, $.getJSON() is a shorthand method, but then you need to append
'callback=?'
to the url as GET parameter (yes, value is ?, jQuery replaces this with its own generated callback method).JSONP 是一个不错的选择,但还有一种更简单的方法。您只需在服务器上设置
Access-Control-Allow-Origin
标头即可。将其设置为*
将接受来自任何域的跨域 AJAX 请求。 (https://developer.mozilla.org/en/http_access_control)执行此操作的方法因语言而异, 当然。 Rails 中的情况如下:
在此示例中,
say_hello
操作将接受来自任何域的 AJAX 请求并返回“hello!”响应。以下是它可能返回的标头示例:
尽管很简单,但它确实有一些浏览器限制。请参阅http://caniuse.com/#feat=cors。
JSONP is a good option, but there is an easier way. You can simply set the
Access-Control-Allow-Origin
header on your server. Setting it to*
will accept cross-domain AJAX requests from any domain. (https://developer.mozilla.org/en/http_access_control)The method to do this will vary from language to language, of course. Here it is in Rails:
In this example, the
say_hello
action will accept AJAX requests from any domain and return a response of "hello!".Here is an example of the headers it might return:
Easy as it is, it does have some browser limitations. See http://caniuse.com/#feat=cors.
您可以通过添加 Access-Control-Allow-Origin 通过 HTTP 标头进行控制。将其设置为 * 将接受来自任何域的跨域 AJAX 请求。
使用 PHP 非常简单,只需将以下行添加到您想要从域外部访问的脚本中:
不要忘记在 httpd.conf 中启用 mod_headers 模块。
You can control this via HTTP header by adding Access-Control-Allow-Origin. Setting it to * will accept cross-domain AJAX requests from any domain.
Using PHP it's really simple, just add the following line into the script that you want to have access outside from your domain:
Don't forget to enable mod_headers module in httpd.conf.
您需要查看同源政策:
为了能够获取数据,它必须是:
相同的协议和主机
您需要实现JSONP 来解决它。
You need to have a look at Same Origin Policy:
For you to be able to get data, it has to be:
Same protocol and host
You need to implement JSONP to workaround it.
我必须从本地磁盘“file:///C:/test/htmlpage.html”加载网页,调用“http://localhost/getxml.php”url,并在 IE8+ 和 Firefox12+ 浏览器中执行此操作,使用 jQuery v1 .7.2 lib 以最小化样板代码。看了几十篇文章终于明白了。这是我的总结。
这是一个带有一些调试系统输出的 jQuery ajax 调用示例。
I had to load webpage from local disk "file:///C:/test/htmlpage.html", call "http://localhost/getxml.php" url, and do this in IE8+ and Firefox12+ browsers, use jQuery v1.7.2 lib to minimize boilerplate code. After reading dozens of articles finally figured it out. Here is my summary.
Here is an example jQuery ajax call with some debug sysouts.
诚然,同源策略会阻止 JavaScript 跨域发出请求,但 CORS 规范只允许您正在寻找的 API 访问类型,并且当前一批主要浏览器都支持该 API。
了解如何为客户端和服务器启用跨域资源共享:
http://enable-cors.org/
“跨源资源共享 (CORS) 是一种能够实现跨域边界真正开放访问的规范。如果您提供公共内容,请考虑使用 CORS 将其开放以进行通用 JavaScript/浏览器访问。”
It is true that the same-origin policy prevents JavaScript from making requests across domains, but the CORS specification allows just the sort of API access you are looking for, and is supported by the current batch of major browsers.
See how to enable cross-origin resource sharing for client and server:
http://enable-cors.org/
"Cross-Origin Resource Sharing (CORS) is a specification that enables truly open access across domain-boundaries. If you serve public content, please consider using CORS to open it up for universal JavaScript/browser access."
这是可能的,但您需要使用 JSONP,而不是 JSON。斯特凡的链接为您指明了正确的方向。 jQuery AJAX 页面 提供了有关 JSONP 的更多信息。
Remy Sharp 有一个使用 PHP 的详细示例。
This is possible, but you need to use JSONP, not JSON. Stefan's link pointed you in the right direction. The jQuery AJAX page has more information on JSONP.
Remy Sharp has a detailed example using PHP.
我使用 Apache 服务器,所以我使用了 mod_proxy 模块。启用模块:
然后添加:
最后,将 proxy-url 传递给您的脚本。
I use Apache server, so I've used mod_proxy module. Enable modules:
Then add:
Finally, pass proxy-url to your script.
浏览器安全性可防止从一个域托管的页面到另一个域托管的页面进行 ajax 调用;这称为“同源策略”。
Browser security prevents making an ajax call from a page hosted on one domain to a page hosted on a different domain; this is called the "same-origin policy".
来自 Jquery 文档(链接):
由于浏览器安全限制,大多数“ Ajax”请求遵循同源策略;该请求无法成功检索来自不同域、子域或协议的数据。
脚本和 JSONP 请求不受同源策略限制。
所以我认为您需要使用 jsonp 来请求。但我自己还没有尝试过这个。
From the Jquery docs (link):
Due to browser security restrictions, most "Ajax" requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, or protocol.
Script and JSONP requests are not subject to the same origin policy restrictions.
So I would take it that you need to use jsonp for the request. But haven't tried this myself.
使用 JSONP 的示例很少,其中包括错误处理。
但是,请注意,使用 JSONP 时不会触发错误事件!请参阅: http://api.jquery.com/jQuery.ajax/ 或 使用 jsonp 的 jQuery ajax 请求错误
There are few examples for using JSONP which include error handling.
However, please note that the error-event is not triggered when using JSONP! See: http://api.jquery.com/jQuery.ajax/ or jQuery ajax request using jsonp error
我知道解决您问题的 3 种方法:
首先,如果您有权访问这两个域,则可以使用以下方式允许访问所有其他域:
header("Access-Control-Allow-Origin: *");
或者只是通过将以下代码添加到 .htaccess 文件中来创建一个域:
SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0
标头添加 Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
您可以向服务器中的 php 文件发出 ajax 请求,并使用此 php 文件处理对另一个域的请求。
I know 3 way to resolve your problem:
First if you have access to both domains you can allow access for all other domain using :
header("Access-Control-Allow-Origin: *");
or just a domain by adding code bellow to .htaccess file:
<FilesMatch "\.(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</IfModule>
</FilesMatch>
you can have ajax request to a php file in your server and handle request to another domain using this php file.
只需将其添加到所提供的页面中,它就可以在 PHP 中工作:
PS:我已经使用方便且有用的方法制作了自己的 xhr 套件,名为 sa_ajax。 (https://github.com/osergioabreu/sa_ajax/)
It got to work in PHP just adding this to the page served:
PS: I have made my own xhr suite called sa_ajax with handy and useful methods. (https://github.com/osergioabreu/sa_ajax/)
对于 Microsoft Azure,情况略有不同。
Azure 有一个需要设置的特殊 CORS 设置。这在幕后本质上是相同的,但简单地设置 joshuarh 提到的标题是行不通的。可以在此处找到用于启用跨域的 Azure 文档:
https://learn.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript
我摆弄了这个几个小时后才意识到我的托管平台有这种特殊设置。
For Microsoft Azure, it's slightly different.
Azure has a special CORS setting that needs to be set. It's essentially the same thing behind the scenes, but simply setting the header joshuarh mentions will not work. The Azure documentation for enabling cross domain can be found here:
https://learn.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript
I fiddled around with this for a few hours before realizing my hosting platform had this special setting.
它可以工作,您需要的一切:
PHP:
JS(jQuery ajax):
it works, all you need:
PHP:
JS (jQuery ajax):