跨域漫谈

这里主要描述跨域的一些细节

set-cookie被阻止

浏览器在请求一个设置 session 的接口,如果和当前域名不一致,则出现上述这种情况

比如当前浏览器访问地址:http://www.example.com
如果请求接口:http://www.test.com/api,那么就会出现上述提示,这种提示就表明了该接口下的 cookie 没有正常写入,即 cookie 写入失败

解决方案: - session 配置设置如下
go session.Options(sessions.Options{MaxAge: 3600 * 12, Path: "/", HttpOnly: true, SameSite: http.SameSiteNoneMode, Secure: true}) - 请求接口使用https
即访问地址:https://www.test.com/api,那么 cookie 就可以正常写入了

但是内部系统,往往没有使用 https,如果还需要这种情况进行 cookie 写入,就可以考虑自动提交 form 表单

1
2
3
4
5
6
7
8
9
10
11
12
// form提交js代码说明
const div = document.createElement("div");
div.innerHTML = `
<form id="login-form" method="POST" action="http://www.test.com/api">
<input name="secret" type='hidden' value='${responseData.data}'/>
</form>
`;
document.body.appendChild(div);

const run = document.createElement("script");
run.innerHTML = `document.getElementById("login-form").submit();`;
document.body.appendChild(run);

这样,cookie 就正常在www.test.com这个域名下写入了,这个时候别忘了加个回调地址,再重定向回原来访问的页面

已经注入 cookie,跨域请求时,cookie 协带说明

通常,我们使用 fetch 函数请求接口,服务端解除跨域限制且支持 cookie 接收,一般这样设置

前端

1
2
3
4
fetch("http://www.test.com/api/list", {
// 支持携带cookie
credentials: "include",
});

后端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// c表示 *gin.Context

method := c.Request.Method
origin := c.Request.Header.Get("Origin")

if origin != "" {
c.Header("Access-Control-Allow-Origin", origin)
//服务器支持的所有跨域请求的方法
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE, PATCH")
// 允许跨域设置可以返回其他子段,可以自定义字段
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token,Authorization,Token,ops_env,ops_version")
// 允许浏览器(客户端)可以解析的头部 (重要)
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
// 允许客户端传递校验信息比如 cookie (重要)
c.Header("Access-Control-Allow-Credentials", "true")
}

//放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}

但是注意,这个时候,你的 cookie 并没有带到后端,因为浏览器访问的地址是http://www.example.com,但是请求的接口是http://www.test.com/api/list

也就说,http://www.test.com/api/这里的 cookie 写入,肯定是在.test.com这个域名下的,而由于当前访问的域名是.example.com,这个时候 cookie 就没有办法带过去

只有请求这种地址的跨域是可以的http://api.example.com/list