HTTP访问控制 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
解决跨域的方式有很多种,本文介绍“跨域请求附带发送cookie”
一、测试环境
前提:后台使用apache+php实现。apache设置多个虚拟主机,设置方式参考:http://www.cnblogs.com/sivkun/p/7347978.html
在http://a.sivkun.com域中/cors-cookie/目录下有文件:
1. index.php
<?php
session_start();
setcookie('a.a','a.a');
setcookie('a.sivkun','a.sivkun',time()+3600*24,'/',"a.sivkun.com");
include_once 'index.html';
?>
2. index.html
<!DOCTYPE html>
<html lang="en"> <head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<script>
fetch('http://b.sivkun.com/cors-cookie/api.php', {
credentials: "include" //表示发送请求附带域b.sivkun.com下cookie
}).then(function (response) {
console.log(response);
return response.json();
}).then(function (data) {
console.log('cookie',data)
})
</script>
</body> </html>
在http://b.sivkun.com域中/cors-cookie/目录下有文件:
1. api.php(有问题的代码)
<?php
session_start();setcookie("bbbbb","bbbbb");
setcookie('b.sivkun','b.sivkun',time()+3600*24,'/',"b.sivkun.com");
echo json_encode($_COOKIE);
?>
正确的方式
1. api.php(修正后的代码)
<?php
session_start();
header("Access-Control-Allow-Origin:http://a.sivkun.com");
header("Access-Control-Allow-Credentials: true");
setcookie("bbbbb","bbbbb");
setcookie('b.sivkun','b.sivkun',time()+3600*24,'/',"b.sivkun.com");
echo json_encode($_COOKIE);
?>
接下来是一步步的解决过程,不想看可以不看。
二、开启附带cookie跨域
上面的代码运行是有问题的
报错:
1.这里要求http://b.sivkun.com/cors-cookie/api.php.设置header。
index.php:1 Fetch API cannot load http://b.sivkun.com/cors-cookie/api.php.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://a.sivkun.com' is therefore not allowed access.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
修改:api.php,添加`Access-Control-Allow-Origin:*`头,允许所有跨域请求
<?php
session_start();
header("Access-Control-Allow-Origin:*");
setcookie("bbbbb","bbbbb");
setcookie('b.sivkun','b.sivkun',time()+3600*24,'/',"b.sivkun.com");
echo json_encode($_COOKIE);
?>
2.这里提示如果请求使用“include”证书模式,需要把`*`改为http://a.sivkun.com。
Fetch API cannot load http://b.sivkun.com/cors-cookie/api.php.
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
Origin 'http://a.sivkun.com' is therefore not allowed access.
修改:api.php
<?php
session_start();
header("Access-Control-Allow-Origin:http://a.sivkun.com");
setcookie("bbbbb","bbbbb");
setcookie('b.sivkun','b.sivkun',time()+3600*24,'/',"b.sivkun.com");
echo json_encode($_COOKIE);
?>
3.接下来报错,说要添加`Access-Control-Allow-Credentials`头部,加上呗
Fetch API cannot load http://b.sivkun.com/cors-cookie/api.php.
The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.
Origin 'http://a.sivkun.com' is therefore not allowed access.
api.php
<?php
session_start();
header("Access-Control-Allow-Origin:http://a.sivkun.com");
header("Access-Control-Allow-Credentials: true");
setcookie("bbbbb","bbbbb");
setcookie('b.sivkun','b.sivkun',time()+3600*24,'/',"b.sivkun.com");
echo json_encode($_COOKIE);
?>
控制太输出:说明cookie是发过去了的。
最后看一下应用的cookie信息:Cookies选项中,在`a.sivkun.com`中可以看到包括`b.sivkun.com`所有的cookie信息。
接下来在控制台操作一下cookie,发现只有a.sivkun.com这个域中设置的cookie,说明浏览器限制javascript是不可以跨域操作cookie的。如下图: