需求
从A网站,跳转到B网站,并且把A网站的登录token,带到B网站,使B网站处于登录状态
【此方法 如果使用cookie作为登录状态,在A、B为非同站点(SameSite)的情况下不会生效,因为iframe 在非 同站点 的情况下无法携带cookie, 参考,参考】
所以可以使用localstorage,localstorage在iframe中使用没有限制, 但是localstorage二级域名和根域名不能共享,除非手动在二级域名下设置document.domain = “根域名”!在iframe中更新localstorage会会被同步更新到网站中
实现方法
A网站的代码
- // A网站 Button按钮的方法
- function openB() {
- const iframeEle = document.createElement('iframe');
- iframeEle.src = `https://B.com/authPage?t=${Math.random(1, 100)}`;
- iframeEle.id = 'iframeEle';
- iframeEle.setAttribute('data-url','https://B.com/');
- iframeEle.style.display = 'none';
- document.body.appendChild(iframeEle);
- }
-
- // A 网站中 test.vue的mounted()方法 (或者其他的初始化方法)
-
- function mounted() {
- // 监听message方法
- window.addEventListener('message', receiveMessage);
- }
-
-
- function receiveMessage(e) {
- const iframeEle = document.getElementById('iframeEle');
- if (e.data?.action === 'isReady') {
- iframeEle.contentWindow.postMessage(
- {
- token: 'this is your token in A website',
- action: 'setToken'
- },'*');
- }
- if (e.data?.action === 'close') {
- const url = iframeEle.getAttribute('data-url');
- document.body.removeChild('iframeEle');
- // 接收到关闭消息时,跳转到B网站
- window.location.href = url;
- }
- }
B 网站的代码
- // B 网站的mounted方法
- function mounted() {
- // window.parent 说明是在iframe中引入的
- if (window.parent) {
- window.parent.postMessage({ action: 'isReady' }, '*')
- window.addEventListener('message', receiveMessage, false)
- }
- }
-
- function receiveMessage(e) {
- if (e.data && e.data.action === 'setToken') {
- // 使用新token 登录
- loginByToken(e.data.token).finally(() => {
-
- // 注意,这里要在loginByToken里面的异步请求,都完成之后才发送close消息
- // 否则,如果loginByToken中的请求没返回,就发消息让A网站执行跳转操作
- // B网站就不会登录成功,因为未返回的请求被浏览器给取消了!!
- e.source.postMessage({ action: 'close' }, '*')
- })
- }
-
- }
关于postMessage的相关知识请看官网
扩展知识
1. 同源和同站的区别
Cookie 的 SameSite 属性 - 阮一峰的网络日志
https://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html