一、Jsonp实现
先来简单介绍一下jsonp:JSONP(JSON with Padding)是Json的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
注:需要注意的地方看代码注释。
我们在www.ascexz.com域名下的服务器放一个html文件加入如下js代码,请求www.107lab.com域下的资源
js代码:
$.ajax({
type:'POST',//注意:jsonp只支持get请求,这里写的post在请求时也会被自动改成get下面的data:里的json数据服务器接收不到
url:'http://www.107lab.com/cross.php',
dataType:'jsonp', //注意:预期服务器返回的类型要设置成jsonp格式
jsonp:'callback', //注意:这里指定回掉函数,请求时url会变成www.107lab.com/cross.php?callback=?
data:JSON.stringify({
'name':'王八'
}),
success: function(data){
alert(data.name+"\n");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("请求错误:"+errorThrown);
}
});
www.107lab.com域下的cross.php文件
$json = file_get_contents("php://input");//这里我们试图接收jsonp方式post过来的数据,但是接收不到
$callback = $_GET['callback'];
$json = empty($json)?'{"name":"服务器没接收到数据"}':$json;
echo $callback."(".$json.")";//注意:这里要用get到的callback把返回的数据括起来,格式为:callback(json);这样ajax才能正确解析返回的数据,
返回数据的时候不要直接写成 echo 'callback('.$json.')'; callback的值是浏览器自动指定的,如果要自己指定,可将js代码中的jsonp:'callback'改成jsonpCallback:'you_set' 这样你会发现请求时url会变成www.107lab.com/cross.php?callback=you_set
下面看一下结果:
很明显服务器并没有接收到ajax指定的data下的数据
二、服务器端设置Access-Control-Allow-Origin
Access-Control-Allow-Origin:允许访问的域名
跨域资源共享(CROS)机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。
在服务端加上header("Access-Control-Allow-Origin: http://www.ascexz.com");
如果将http://www.ascexz.com换成 * 则为允许所有域名访问服务器资源
实现如下:
js代码:
$.ajax({
type:'POST',
url:'http://www.107lab.com/cross.php',
dataType:'json',
data:JSON.stringify({
'name':'王八'
}),
success: function(data){
alert(data.name+"\n");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
alert("请求错误:"+errorThrown);
}
});
cross.php中的代码:
header('Access-Control-Allow-Origin:*');
$json = file_get_contents("php://input");
$json = empty($json)?'{"name":"服务器没接收到数据"}':$json;
echo $json;
看一下效果:
服务器成功接收到post上传的数据
注意:ajax里不要指定contentType不然会出现如下错误,跨域请求会被拦截