Chrome80版本跨域请求接口未携带cookie

630 阅读2分钟
转载原文:blog.csdn.net/lihefei_cod…

背景:同一个脚手架开发的项目,一个项目请求接口会携带cookie,另一个项目cookie带不过去,通过各种方式去调试,包括whistle反向代理,抓包,debugger等方式,都找不到问题所在,最后通过上文,才发现是浏览器版本在跨域请求中,需要使用域名访问,ip + port不行。

这篇问题解决了项目中遇到的看似很诡异的问题

1.前端在登录界面填写帐号密码发送登录请求接口验证身份 2.后端验证登录的帐号密码匹配成功后生成一个JSESSIONID身份标识,通过响应头Set-Cookie:JSESSIONID=xxxxx返回给浏览器 3.浏览器接收到响应头中的Set-Cookie指令后将JSESSIONID=xxxxx身份标识保存在Cookie中。 4.前端接收到后端返回登录成功的响应后,路由后正常跳转到业务界面 5.业务界面如果要展示实时数据,需要发送携带JSESSIONID=xxxxx身份标识的请求向后端获取数据 6.但因跨域安全策略的原因,浏览器在发送时并未携带JSESSIONID=xxxxx身份标识 7.后端接收到前端获取业务数据的请求,发现接口没有携带JSESSIONID身份证明,于是拒绝了请求并返回无权限的code码 8.前端接收到后端返回无权限的code码后,路由又跳转到登录界面,需要填写帐号密码重新登录授权 9.登录后取业务数据的请求无权限,又回到登录页面,这样就形成了死循环

解决方案1:手动修改浏览器策略(不推荐,用户体验太差)

1.如果是用axios请求接口,先设置 axios.defaults.withCredentials = true

2.打开谷歌浏览器在Chrome中访问chrome://flags

3.搜索SameSite,把搜到的结果项都设置为disabled,然后重启浏览器,如下图

解决方案2:代理转发同域请求(推荐)

1.如果是用axios请求接口,先设置 axios.defaults.withCredentials = true

2.前端把axios.defaults.baseURL接口指向当前页面域名+指定标识(如/api),中间用Nginx将域名接口中带/api的请求代理到后端实际的接口地址

axios.defaults.baseURL = 'http://www.xxx.com/api';
axios.get('/news').then();

Nginx配置:

server {
    listen       80;
    server_name  localhost;

    #把域名包含/api前缀的接口地址都代理到后端接口
    location /api {
        proxy_pass http://www.yyy.com:8888; #后端接口地址
    }
    error_page   500 502 503 504  /50x.html;
        location = /50x.html {
        root   html;
    }
}

假如开发环境没有做代理转发,打包到生产环境需要做域名代理转发,域名是动态的情况下,vue项目在main.js新增生产环境模式下动态获取域名设置到axios.defaults.baseURL

if (process.env.NODE_ENV === 'production') {
    axios.defaults.baseURL = window.location.origin + '/api';
}