ps怎么艺术字字体设计网站,wordpress获取qq头像,织梦app网站模板,一级建造师招聘网最新招聘背景新版chrome(80)浏览器默认屏蔽所有三方cookie已经不是什么新闻了#xff0c;具体原因这里不去深究#xff0c;有大量相关文章介绍#xff0c;由于目前许多网站都依赖三方cookie#xff0c;因此该特性的推出还是造成了一些的影响#xff0c;比如收集用户信息的广告商)浏览器默认屏蔽所有三方cookie已经不是什么新闻了具体原因这里不去深究有大量相关文章介绍由于目前许多网站都依赖三方cookie因此该特性的推出还是造成了一些的影响比如收集用户信息的广告商而且主流的浏览器都跟进chrome的策略已经成为了既定事实本篇文章主要聚焦于各种解决方案大家可以针对自身情况采用不同的解决办法。限制说明SameSitecookie新增的属性取值包括Lax(默认),None,Strict1.None 将关闭SameSite属性前提是必须同时设置Secure属性Cookie 只能通过 HTTPS 协议发送否则无效2.Strict 严格模式完全禁止第三方 Cookie跨站点时任何情况下都不会发送 Cookie。换言之只有当前网页的 URL 与请求目标一致才会带上 Cookie3.Lax 规则稍稍放宽大多数情况也是不发送第三方 Cookie但是导航到目标网址的 Get 请求除外具体可参考文末链接【1】总数所述要解决我们的问题要么都是同一域名一劳永逸要么采用https协议SameSitenone或者不用新版浏览器除此之外好像也没有什么办法了(如果有请告诉我-_-)。解决方案1.chrome设置这种方式比较简单手动禁用浏览器的限制功能可参考文末链接【2】2.使用低版本浏览器这也是一种解决方式但是不推荐3.https协议 SameSiteNone这主要依赖运维和后端处理了但是这种方式在以后新版浏览器中可能会失效因为过两年浏览器将全面禁止三方cookie到时候怎么设置都不起作用了4.代理服务如果上面的方式都不满足可以考虑采用node作为请求-应答的中间层大体设计如图前端项目和代理服务位于同一个服务器协议和域名一致只是端口不同而已为什么要这么设计呢便于cookie共享 因为cookie是不区分协议和端口的因此只要域名(或者ip)一致那么在同一台电脑上就可以读取同域名下的cookie 。还需要说明的一点就是跨域问题是浏览器的安全策略对于代理服务和后端服务来说就没有跨域一说了而是进程间的通信。接下来我们实现一个比较简单的三方cookie请求示例其中各个服务的访问地址如下(都是本地模拟因此代理和后端服务的ip一致而真实情况往往不同)前端项目: http://127.0.0.1:8000node代理服务: http://127.0.0.1:8001后端服务: http://127.0.0.1:8002示例演示与流程1.登录验证首先需要输入正确的用户信息获取cookie这里我们使用iframepostmessage的方式实现跨域登录请求流程分为1.访问http://127.0.0.1:8000,打开登陆界面输入用户名和密码2.点击登录登录页面通过postMessage将登录信息发送给http://127.0.0.1:8001页面这个页面获取登录信息后调用http://127.0.0.1:8001/login登录接口3.请求到node代理服务后端然后发起对真正的服务后端请求然后将后端服务的响应返回给前端页面4.如果校验成功响应头会携带Set-Cookie信息在http://127.0.0.1:8001的域下写入cookie同时http://127.0.01:8000也会写入同样的cookie2.cookie读取成功登录之后在http://127.0.0.1:8000和http://127.0.0.1:8001都保存有cookie实现了共享可以通过document.cookie获取如果服务端返回的cookie是httponly这时可以在代理服务层将这个属性去掉就可以读取了。3.查询数据发起信息查询时需要携带登陆成功后设置的cookie这里就不通过iframepostMessage的方式了直接调用8001的接口服务但是要注意一点的就是 由于是跨域的脚本请求因此是不会自动携带cookie信息的(即便是在客户端可以实现cookie共享) 如果设置withcredentials相关属性则还是三方cookie跨域的问题是不容许携带cookie的因此我们需要手动设置一个请求头 _cookie(cookie前面加了个下划线前缀) 将cookie带上去。8001上的代理获取到查询请求时解析请求头的_cookie参数然后重新设置请求头的cookie参数再发送给真正的后端服务接口这时候就可以实现cookie的校验了。4.代码实现文件结构图1.) 前端项目bodyiframe srchttp://127.0.0.1:8001/iframe !--代理服务首页提供登录功能--divlabel姓名/labelinput typetext idname /brlabel密码/labelinput typepassword idpassbrbutton idbtn-login登录/button/div/bodyscript typetext/javascriptvar proxyHost http://127.0.0.1:8001;window.onload function() {window.addEventListener(message, receiveMessage, false);document.querySelector(#btn-login).addEventListener(click, function login() {window.frames[0].postMessage({ // 发送跨域登录请求到iframe页面url: /login,payload: {name: document.querySelector(#name).value,pass: document.querySelector(#pass).value,}}, proxyHost);}, false);}function receiveMessage(event) {if (event.origin ! proxyHost) {return;}if (event.data.code 0) { // 登录成功fetchUser();}}function fetchUser() { // 查询用户信息$.ajax({type : POST,contentType: application/json,url : proxyHost /fetchUser,headers: {_cookie: document.cookie, // 自定义请求头_cookie},success : function(result) {console.log(fetchUser success:, result);},error : function(e){console.log(fetchUser error:, e);}});}/script2.) node代理服务---http://127.0.0.1:8001---script typetext/javascriptvar appHost http://127.0.0.1:8000;function login(event) { // 调用代理服务登录接口$.ajax({type : POST,contentType: application/json,data: JSON.stringify(event.data.payload),url : /login,success : function(result) {event.source.postMessage(result, event.origin); // 调用成功发送返回数据给用户页面},error : function(e){event.source.postMessage(e, event.origin);}});}function receiveMessage(event) {if (event.origin ! appHost) {return;}if (event.data.url /login) {login(event);}}window.addEventListener(message, receiveMessage, false);/script---代理服务脚本---......const CORS_HEADER {Access-Control-Allow-Origin: http://127.0.0.1:8000,Access-Control-Allow-Headers: Content-Type, _cookie,Access-Control-Allow-Credentials: true,};......function sendProxyRequest(req, res) {const { method, headers, url } req;const chunks [];if(Object.hasOwnProperty.call(headers, _cookie)) { // 包含自定义_cookie请求头重新设置cookieheaders.cookie headers._cookie;}req.on(data, (chunk) {chunks.push(chunk);});req.on(end, () {const request http.request({ // 发送请求到后端服务host: 127.0.0.1,port: 8002,path:url,method,headers,}, (response) {res.writeHead(response.statusCode, {...CORS_HEADER,...response.headers,});response.pipe(res);});request.end(Buffer.concat(chunks).toString());});}3.) 后端服务......const { method, headers, url } req;const _method method.toLowerCase();if (url /login _method post) { // 登录验证const chunks [];req.on(data, (chunk) {chunks.push(chunk);});req.on(end, () {const result {code: -1,message: login fail,};const resHeaders {Content-Type: text/json,};const { name, pass } JSON.parse(Buffer.concat(chunks).toString());if (name 123 pass abc) { // 这里只校验123abc这种情况result.code 0;result.message login success;resHeaders[Set-Cookie] sidabc; Max-Age${getCookieExpires()};; // 设置cookie}res.writeHead(200, resHeaders);res.end(JSON.stringify(result));});......return;}if (url /fetchUser _method post) { // 用户信息查询if (req.headers.cookie sidabc) { // 校验cookieres.writeHead(200, {Content-Type: text/json,});......} else {res.writeHead(401);res.end();}return;}总结第四种方法可以不修改后端服务微调前端项目即可因此对于现有项目改造成本较低但是需要维护一个node服务代理上面的示例演示了http协议对于https站点只需要稍微修改下node代理服务即可(https模块根证书)最后再说一点在前后端分离模式下开发过程中遇到这样的问题可以设置webapck的服务代理具体可参考资料【4】本文就讲到这里大家如果有更好的解决方案欢迎留言交流。参考资料【1】http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html【2】https://www.cnblogs.com/Summer6/p/11671204.html【3】https://juejin.im/post/6844904128557105166【4】https://www.yuque.com/mdtvv0/myv5bw/es2oeo