这里有两个页面,test.php和testerver.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
现在我的问题是:当这两个文件都在同一台服务器上时(无论是localhost还是web服务器),它可以工作,并且alert("Success")
被调用;如果它在不同的服务器上,即web服务器的testerver.php和localhost的test.php,它不能工作,并且alert("Error")
被执行。即使ajax里面的URL被改成http://domain.com/path/to/file/testserver.php
使用JSONP。
jQuery。
$.ajax({
url:"testserver.php",
dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
success:function(json){
// do stuff with json (in this case an array)
alert("Success");
},
error:function(){
alert("Error");
}
});
PHP:
<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>
echo可能是错误的,我已经有一段时间没有使用php了。在任何情况下,你需要输出callbackName('jsonString')
注意引号。jQuery将传递它自己的回调名称,所以你需要从GET参数中获取。
正如Stefan Kendall所说,$.getJSON()是一个速记方法,但是你需要在url上附加'callback=?'
作为GET参数(是的,值是?,jQuery用自己生成的回调方法代替)。
JSONP是一个很好的选择,但是有一个更简单的方法。
你可以简单地在你的服务器上设置Access-Control-Allow-Origin
头。
将它设置为 "*"将接受来自任何域的跨域AJAX请求。
([https://developer.mozilla.org/en/http_access_control][1])
当然,不同的语言会有不同的方法。 下面是Rails中的方法。
class HelloController < ApplicationController
def say_hello
headers['Access-Control-Allow-Origin'] = "*"
render text: "hello!"
end
end
在这个例子中,say_hello
动作将接受来自任何域的AJAX请求,并返回一个"hello!"的响应。
下面是它可能返回的头信息的一个例子。
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive
虽然简单,但它确实有一些浏览器的限制。 参见http://caniuse.com/#feat=cors。
你可以通过HTTP头添加Access-Control-Allow-Origin来控制。 将其设置为*,将接受来自任何域的跨域AJAX请求。
使用PHP真的很简单,只需在你想从你的域外访问的脚本中添加以下一行。
header("Access-Control-Allow-Origin: *");
不要忘记在httpd.conf中启用mod_headers模块。
我不得不从本地磁盘加载网页"file:///C:/test/htmlpage.html",调用"http://localhost/getxml.php" url,并在IE8+和Firefox12+浏览器中进行,使用jQuery v1.7.2 lib尽量减少模板代码。 看了几十篇文章终于弄明白了。 下面是我的总结。
下面是一个jQuery的ajax调用示例,其中包含一些调试sysouts。
jQuery.support.cors = true;
$.ajax({
url: "http://localhost/getxml.php",
data: { "id":"doc1", "rows":"100" },
type: "GET",
timeout: 30000,
dataType: "text", // "xml", "json"
success: function(data) {
// show text reply as-is (debug)
alert(data);
// show xml field values (debug)
//alert( $(data).find("title").text() );
// loop JSON array (debug)
//var str="";
//$.each(data.items, function(i,item) {
// str += item.title + "\n";
//});
//alert(str);
},
error: function(jqXHR, textStatus, ex) {
alert(textStatus + "," + ex + "," + jqXHR.responseText);
}
});
有一些使用JSONP的例子,其中包括错误处理。
然而,请注意,当使用JSONP时,错误事件并没有被触发! 请看 http://api.jquery.com/jQuery.ajax/ 或 https://stackoverflow.com/questions/5247295/jquery-ajax-request-using-jsonp-error
来自Jquery文档([链接][1])。
由于浏览器的安全限制,大多数"Ajax" 请求都受制于相同的来源策略。 请求不能成功地从不同的域、子域或协议中检索数据。
脚本和JSONP请求不受相同的起源策略限制。
所以我认为你需要使用jsonp进行请求。 但是自己还没有尝试过。
我知道3种方法可以解决你的问题。
header("Access-Control-Allow-Origin: *");
或者通过在.htaccess文件中添加下面的代码来允许一个域名的访问。
`<FilesMatch "(ttf|otf|eot|woff)$">
你可以使用jsonp,因为它不需要权限。 关于这一点,你可以阅读我们的朋友@BGerrissen的回答。
**对于Microsoft Azure来说,略有不同。
Azure 有一个需要设置的特殊 CORS 设置。 在幕后基本上是一样的,但简单地设置joshuarh提到的标题将不起作用。 关于启用跨域的Azure文档可以在这里找到。
https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript
我摆弄了几个小时,才发现我的主机平台有这个特殊设置。
它的工作原理,所有你需要的。
PHP。
header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
JS(jQuery ajax)。
var getWBody = $.ajax({ cache: false,
url: URL,
dataType : 'json',
type: 'GET',
xhrFields: { withCredentials: true }
});