同源问题
协议,域名,端口任意一个不同的话,都是不同源网址.
同源意味着两个请求地址只在路径上有不同.
基于网络安全,默认的,ajax不允许不同源的访问
示例:
//当前页面是sitea.io/sitea-index.php
$(function () {
$.ajax({
url:"http://siteb.io/siteb-time.php",
success:function (res){
console.log(res);
}
});
})
复制代码
Access to XMLHttpRequest at 'http://siteb.io/siteb-time.php' from origin 'http://sitea.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这是一个十分经典的错误,以前做客户端开发的时候也遇到过,但是不明白是什么问题.
在sitea.io访问siteb.io下面的数据,被CORS策略阻塞,在request header中需要设置Access-Control-Alllow-Origin.
问题的核心在于获取不同源页面的数据
1. 通过img标签可以当前页面访问到不同源数据
<!-- 当前页面为http://sitea.io/sitea-index.php -->
<img src="http://siteb.io/img/02.jpeg">
复制代码
那么如果把图片连接换成一个php文件呢?
<img src="http://siteb.io/siteb-time.php">
//siteb-time.php 代码
<?php
echo time();
?>
复制代码
虽然请求siteb-time.php状态码为200,是ok的,但是浏览器默认按照图片处理,无法访问response
2. 通过link标签可以获取跨域请求
//sitea-index.php代码
<link rel="stylesheet" type="text/css" href="http://siteb.io/css/style.css">
复制代码
请求http://siteb.io/css/style.css
但是没办法使用代码操作响应
那么link标签的href放一个php标签呢?并且修改rel和type,能这样做吗?link标签可以做那些事?
强行链接一个php文件,会发生什么呢?
<link rel="stylesheet" type="text/css" href="http://siteb.io/siteb-time.php">
复制代码
请求资源可以成功,但是不能操作响应
3.script标签可以引入外部js文件
强行src链接一个php文件
<script type="text/javascript" src="http://siteb.io/siteb-time.php"></script>复制代码
会发生什么呢?
照样可以获取到php文件的内容,但是如何操作呢?可不可以服务端返回js代码?,那么客户端实际执行到一段js代码
script标签既可以引入一个外部脚本,也可以包含脚本语句.服务端中获取到数据之后,调用一个服务端定义好的函数,把响应数据作为参数,不就可以操作到响应了.
客户端代码
<script type="text/javascript">
function foo(data){
console.log(data);
}
</script>
<script type="text/javascript" src="http://siteb.io/siteb-time.php"></script>
服务端代码
<?php
echo "foo(${time()});"
?>复制代码
结果
提示为:
Cross-Origin Read Blocking (CORB) blocked cross-origin response http://siteb.io/siteb-time.php with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.
跨域访问块CORB阻塞了跨域响应
发现是因为传递的参数应该是string类型的
<?php
$arr = array('name' => '张三','age' => 18, 'weight' => 188.6);
$str = json_encode($arr);
$foo = "function foo(res){console.log(res);alert(res);};foo(${str});";
echo $foo;
?>
复制代码
这实际上就解决了跨域问题