跨域是一个老的话题,今天就来看看如何跨域。
1.普通跨域
(在 http://www.webhek.com下请求一个http://www.qiutianaimeili下的接口)
$.ajax({
url:'http://www.qiutianaimeili.com/php/crossDomainJsonp.php',
type:'POST',
data:{name:'nb'},
success:function(data){
console.log('success',data);
},
error:function(data){
console.log('error',data);
}
})
这个是最简单的跨域,服务端设置:
header('Access-Control-Allow-Origin:http://www.webhek.com');
header('Access-Control-Allow-Method:POST, GET,OPTIONS');
echo json_encode(array('name'=>$name,'sex'=>'man','age'=>'18'));
?>
Access-Control-Allow-Origin指定哪些域可以访问。
Access-Control-Allow-Method表示接收的方法。
2.crossDomain:false跨域
(在 http://www.webhek.com下请求一个http://www.qiutianaimeili下的接口)
$.ajax({
url:'http://www.qiutianaimeili.com/php/crossDomainJsonp.php',
type:'POST',
data:{name:'nb'},
crossDomain:false,
success:function(data){
console.log('success',data);
},
error:function(data){
console.log('error',data);
}
})
如果要发送的是相同域,crossDomain默认是false,如果是不同跨域,crossDomain默认是true。
如果是不同域但是设置了crossDomain:false,那么服务端需要设置Access-Control-Allow-Headers:X-Requested-With, Content-Type。这个玩意表示允许ajax。
左边是设置crossDomain为false的请求,右边是crossDoamin为true的请求,我们可以看到,为false的多发送了一个X-Requested-With。
服务端设置:
header('Access-Control-Allow-Origin:http://www.webhek.com');
header('Access-Control-Allow-Method:POST, GET,OPTIONS');
header('Access-Control-Max-Age:10000');
header('Access-Control-Allow-Headers:X-Requested-With, Content-Type');
$name=$_POST['name'];
echo json_encode(array('name'=>$name,'sex'=>'man','age'=>'18'));
?>
3.jsonp跨域
(在 http://www.webhek.com下请求一个http://www.qiutianaimeili下的接口)
$.ajax({
url:'http://www.qiutianaimeili.com/php/crossDomainJsonp.php',
type:'POST',
data:{name:'nb'},
dataType:'jsonp',
jsonp:'fuck_callback',
jsonpCallback:'fuck'
});
var fuck=function(data){
console.log(data);
}
如果是jsonp跨域的话,所有的post都会变成get。jsonp的原理就是变成script标签去加载。
服务端代码:
$name=$_GET['name'];
$callback=$_GET['fuck_callback'];
echo $callback.'("'.$name.'")';
?>
4.withCredentials:true跨域:
(在 http://www.webhek.com下请求一个http://www.qiutianaimeili下的接口)
$.ajax({
url:'http://www.qiutianaimeili.com/php/crossDomainJsonp.php',
type:'POST',
data:{name:'nb'},
xhrFields:{
withCredentials:true
},
success:function(data){
console.log('success',data);
},
error:function(data){
console.log('error',data);
}
})
一般跨域请求的时候是不会带cookie信息的,如果设置withCredentials:true可以带cookie信息。
服务端需要配置header('Access-Control-Allow-Credentials: true');
注意:不能访问不同域的cookie,只能访问相同域的cookie,带过去的也是该域名下的cookie。
同时,用了withCredentials:true之后,不能使用Access-Control-Allow-Origin:*。
header('Access-Control-Allow-Origin:http://www.webhek.com');
header('Access-Control-Allow-Method:POST, GET,OPTIONS');
header('Access-Control-Allow-Credentials: true');
setcookie("name",'123456');
$name=$_POST['name'];
echo json_encode(array('name'=>$name,'sex'=>'man','age'=>'18'));
?>
(上面设置的cookie属于http://www.qiutianaimeili.com域的,不是http://www.webhek.com域的。)
5.contentType:application/json跨域
(在 http://www.webhek.com下请求一个http://www.qiutianaimeili下的接口)
$.ajax({
url:'http://www.qiutianaimeili.com/php/crossDomainJsonp.php',
type:'POST',
data:JSON.stringify({name:'nb'}),
dataType:'json',
contentType:'application/json;charset=utf-8',
success:function(data){
console.log(data);
},
error:function(data){
console.log(data);
}
});
服务器代码
header('Access-Control-Allow-Origin:http://www.webhek.com');
header('Access-Control-Allow-Method:POST, GET,OPTIONS');
header('Access-Control-Max-Age:0');
$json = $GLOBALS['HTTP_RAW_POST_DATA'];
echo $json;
?>
注意这里会产生一个预检请求,就是先用一个OPTIONS方法检查服务器是否允许检查。
Access-Control-Max-Age设置一个预检请求被缓存多久,这是设置为0,方便大家看到预检请求。