同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的 URL 的域必须与当前 Web 页面的域相同。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。
1.通过服务端设置'Access-Control-Allow-Origin'来实现跨域访问
'header' => [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers' => 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With',
//'Access-Control-Allow-Credentials' => 'true',//允许传递cookie
'P3P' => 'CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'
]
当Access-Control-Allow-Credentials这个为true时,也就是允许跨域cookie,这个时候Access-Control-Allow-Origin只能设置一个跨域域名。设置多个浏览器会报错。
Access-Control-Allow-Origin要设置成*或者多个,就不能设置Access-Control-Allow-Credentials该值,也就无法使用cookie传递参数。
关于子域名的cookie共享,只需要在cookie的'domain' 中设置主域名就可以了。例如设置成:
'domain' => '.jianshu.com',
2.jsonp的方式
通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
<script type="text/javascript">
function jsonpCallback(result) {
alert(result.err_msg);
alert(result.result);
}
</script>
<script type="text/javascript" src="http://2.wekjg.sinaapp.com/index.php?m=default&c=goods&a=priceforJsonp&id=10&number=2&callback=jsonpCallback" />
服务端PHP代码
$arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
$result=json_encode($arr);
//动态执行回调函数
$callback=$_GET['callback'];
echo $callback."($result)";
JS客户端代码用jQuery的方法来实现:
$.ajax({
type : "get",
url : "http://2.wekjg.sinaapp.com/index.php?m=default&c=goods&a=priceforJsonp",
data: {'id':10,'attr':'','number':2},
dataType : "jsonp",
jsonp:'callback',
success : function(json){
alert(json.result);
}
});
Jsonp原理:
首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
PS:css字体的跨域问题
如果你把所有的静态文件都统一放到一个域名下,css中需要导入一些字体文件,这是异步导入,此时也发生跨域问题,因此要设置静态文件服务器返回时添加头部信息,如果是nginx就是增加如下配置:
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'X-Requested-With';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
网友评论