首页 > 编程语言 >JavaScript之同站多域名共享Token实现方案

JavaScript之同站多域名共享Token实现方案

时间:2023-09-05 15:56:59浏览次数:52  
标签:JavaScript Token 之同 域名 window iframe 跳转 var

背景

由于公司业务涉及到多个国家,每个国家站的访问的域名不同(指向同一个 Web 服务)
在站内能够切换不同的国家,服务端一个token支持所有国家鉴权
此时需要前端将Token等相关信息共享到即将跳转到的新站点,因为不同域,浏览器不会共享 Cookie

方案

  1. 将 Token 相关信息 通过 URL Query 参数传到新站点
    问题:
    暴露在地址栏的信息过多
    信息过多容易丢失,有概率超出地址栏最大长度限制

  2. 增加一个静态的中转页文件(如:switch-region.html),将 Token 等信息通过 URL Query 参数嵌套在 iframe 中,iframe 中对Query解析并写入新域名,在跳转到新站点
    解决了信息暴露在地址栏的问题,并没有根本解决 方案1 的第二点比如从 http://ke.testing.com 跳转到 http://ng.testing.com

// <!-- ke js -->
// <!-- ...... -->

// 创建一个iframe
const iframe: HTMLIFrameElement = document.createElement('iframe')
iframe.style.height = '0'
iframe.style.border = 'none'
// 先跳转到 switch-region.html 中转页,将 token 等信息带到新域名
iframe.src = `http://ng.testing.com/switch-region.html?Token=xxxxxxxTokenxxxxxxxxxx`

document.body.appendChild(iframe)

// iframe加载,表示token已经写入到新域名中
// 跳转到 ng 站点
iframe.onload = () => {
  setTimeout(() => {
    window.location.href = 'http://ng.testing.com'
  }, 200)
}
<!-- ...... -->
<!-- ng -->
<!-- switch-region.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
  <style></style>
  <script>
    function getUrlParam(name){
      var url = window.location.search; //获取url中"?"符后的字串   
       var theRequest = new Object();   
       if (url.indexOf("?") != -1) {   
          var str = url.substr(1);   
          strs = str.split("&");   
          for(var i = 0; i < strs.length; i ++) {   
             theRequest[strs[i].split("=")[0]]=decodeURI(strs[i].split("=")[1]); 
          }   
       }   
       return theRequest;   
    }

    function setCookie(cName, cValue, exDays){
      var d = new Date();
      d.setTime(d.getTime()+(exDays*24*60*60*1000));
      var expires = "expires="+d.toGMTString();
      document.cookie = cName + "=" + cValue + "; " + expires;
    }

    // 比如获取到url中的 Token,写入新域名的cookie中
    setCookie('Token', getUrlParams('Token'))
  </script>
</head>
<body>
</body>
</html>
  1. postMessage + iframe方案,解决数据量大,及地址栏暴露信息问题
// ke js
const iframe = document.createElement('iframe')
iframe.style.height = '0'
iframe.style.border = 'none'
iframe.src = `http://ng.testing.com/switch-region.html`

document.body.appendChild(iframe)

const token = 'xxxxxxxTokenxxxxxxxxxx'
iframe.onload = () => {
  // 新域名加载完成后发送一个 事件
  iframe.contentWindow?.postMessage(`userinfo|${JSON.stringify({ Token })}`, '*')
}

// 监听 switch-region.htlm 的回调
window.addEventListener('message', (event: any) => {
  if(event.data === 'jump') {
    console.log('---------- jump -----------')

    // 跳转到新域名    
    window.location.href = 'http://ng.testing.com'
    window.removeEventListener('message', () => {})
  }
})
<!-- ng -->
<!-- switch-region.html -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
  <style></style>
  <script>
    function setCookie(cName, cValue, exDays){
      var d = new Date();
      d.setTime(d.getTime()+(exDays*24*60*60*1000));
      var expires = "expires="+d.toGMTString();
      document.cookie = cName + "=" + cValue + "; " + expires;
    }

    window.addEventListener('message', function (event) {
      // 监听上层 window 派发的事件
      if(Object
          .prototype
          .toString
          .call(event.data)
          .slice(8, -1) === 'String'
      ) {
        const [key, value] = event.data.split('|')
        if(key === 'userinfo') {
          setCookie('Token', value)
          
          // 告诉上层 window,cookie写入新域名,可以开始跳转了
          window.parent.postMessage('jump', '*')
          window.removeEventListener('message', () => {})
        }
      }
    })
  </script>
</head>
<body>

</body>
</html>

总结

方案3能完美解决其他两个方案的不足,但是用 iframe 的方式会导致多一次加载(如果使用类似上面 switch-region.html 这种静态中转文件还是很快的),使用 postMessage 通信也会有一些时间上面的损耗(如果只需要带一个 token,用 Query 参数足以)

标签:JavaScript,Token,之同,域名,window,iframe,跳转,var
From: https://www.cnblogs.com/jingxuan-li/p/17679852.html

相关文章

  • JavaScript判断数组是否包含某个值的6种方法
    循环functioncontains(arr,val){for(vari=0;i<arr.length;i++){if(arr[i]===val){returntrue;}}returnfalse;}contains([1,2,3],3);//true使用whilefunctioncontains(arr,val){vari=arr.length;......
  • 原生javascript实现拖拽
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content......
  • 无涯教程-JavaScript - DATE函数
    描述DATE函数返回特定日期的序列号。语法DATE(year,month,day)争论Argument描述Required/Optionalyearyear参数的值可以包含1-4位数字。Excel会根据计算机使用的日期系统解释年份参数。默认情况下,MicrosoftExcelforWindows使用1900日期系统。请参阅下面的......
  • 无涯教程-JavaScript - DVARP函数
    描述DVARP函数通过使用列表或数据库中符合您指定条件的记录的字段(列)中的数字,基于整个总体计算总体的方差。语法DVARP(database,field,criteria)争论Argument描述Required/Optionaldatabase组成列表或数据库的单元格范围。数据库是相关数据的列表,其中相关信息......
  • 无涯教程-JavaScript - DVAR函数
    描述DVAR函数使用与指定条件相匹配的列表或数据库的列中的数字,根据样本估算总体的方差。语法DVAR(database,field,criteria)争论Argument描述Required/Optionaldatabase组成列表或数据库的单元格范围。数据库是相关数据的列表,其中相关信息的行是记录,数据的列......
  • 软件测试|快速、可靠的JavaScript依赖管理工具——yarn
    简介Yarn是一个由Facebook于2016年推出的JavaScript软件包管理器。它的目标是解决npm(Node.js的默认软件包管理器)在性能和可靠性方面的一些问题。Yarn旨在提供更快、更安全、更稳定的依赖项安装过程,使JavaScript开发人员能够更轻松地管理和构建项目。本文将详细介绍Yarn的特点、优势......
  • JavaScript-属性描述对象
    概述JavaScript提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributesobject)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。下面是属性描述对象的一个例子。{value:123,......
  • javascript中的iframe
    上级向iframe传值1.用postMessage在上级用:iframeElement.contentWindow.postMessage("发送的消息内容","*");在iframe内接收消息:window.addEventListener("message",function(ev){let收到的消息=ev.data;.....}); ......
  • 无涯教程-JavaScript - DMAX函数
    描述DMAX函数返回列表或数据库中符合您指定条件的列中的最大数字。语法DMAX(database,field,criteria)争论Argument描述Required/Optionaldatabase组成列表或数据库的单元格范围。数据库是相关数据的列表,其中相关信息的行是记录,数据的列是字段。列表的第一行包......
  • 无涯教程-JavaScript - DCOUNTA函数
    描述DCOUNTA函数返回列表或数据库中符合您指定条件的列中非空白单元格的计数。此函数与DCOUNT函数相似,不同之处在于DCOUNTA函数对所有非空白单元进行计数。DCOUNT函数仅计算包含数值的单元格。语法DCOUNTA(database,field,criteria)争论Argument描述Required/Opti......