window.name也可以跨域通信

背景

公司来了一个业务,让我们的登录对接对方系统的AD域实现免密登录。目前对方能提供的如下

  1. 对方是某国企,需要走的流程比较多,所以还没拿到对方提供的demo。
  2. 经过领导决定暂时先让后端自己实现一套,前端进行模拟。

开发

第一版开发

  1. 前后端去网上找对应的demo
  2. 经过技术调研后,后端自己研究部署了一个AD域验证的服务
  3. 我和后端按照类似下方的OAuth 2.0的流程进行对接,搞定,收工

第二个版本开发(对方提供了对接文档,准备进行对接)

过了几周,我收到了一份对接文档。

对方发了一个AD域的地址,并且有以下的信息

重点有一条信息:前端调用接口页面获取当前电脑域账号和密码

第二个版本开发(梳理思路)

这个跟普通的接口请求不同,是直接返回了个html,前端怎么才能拿到这个页面的信息。

对于这个问题我进行了如下的尝试。

  1. 认证的页面是对方提供的页面。我不能在他的代码中用postmessage进行通信
  2. 直接用iframe进行嵌入,读取dom,这个也不行,因为存在跨域的问题。
  3. 既然都不行,那我用nginx转发,不用浏览器绕过这个跨域的问题,本地可以先用devserver进行测试

第二个版本开发(验证)

  1. 先在网上随意找个页面,就用了菜鸟课程的页面。
  2. 本地测试 本地配置了devServer,先获取下菜鸟课程的html的页面,获取到了没问题
  3. 开发环境验证 在开发环境进行测试,修改了nginx的配置下,接口的返回值中拿到了html的值
  4. 用对方的demo进行验证 ,但是出问题了,仔细检查了下,当输入完域账号的时候,中间是有一个302的过程,所以我的前端是拿不到html的。
  5. 修改nginx的配置再次测试,配置了location和reWrite,修改后还是不行。

我已经毫无办法了,当时我在想,这个会不会对方的文档有问题

请求领导再次沟通

毫无办法的我只能让领导去和他们沟通,要到了他们的测试环境

用他们的测试环境进行了测试,调试了他们测试环境的代码,就发现了下方的关键代码。

js 复制代码
<script>
      var ifr = document.createElement("iframe");
      ifr.id = "iframeId";
      ifr.src =  "./test.html";
      ifr.style.display = "none";
      document.body.appendChild(ifr);
      ifr.onload = () => {
        ifr.onload = () => {
          ifr.contentWindow.close();
        };
        ifr.contentWindow.location = "about:blank";
      };
    </script>

看到了一个window.name,什么东西,就去网上搜了搜

这个时候搜集到了阮一峰老师的文章

这个时候大概理解了,为什么对方提供的demo中有一个window.name了,看下方的控制台的截图

把他们的核心代码拷贝过来,就实现跨域也可以拿到数据。

后来跟以前的领导沟通,确实很早之前,确实会用window.name进行跨域,不过现在用的少了。

window.name的学习

概念

MDN的截图中有如下

通过MDN看这个概念确实很抽象,我们通过例子来看看他的应用场景

例子

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <script>
      var myWindow;
      function openWin() {
        myWindow = window.open("", "MsgWindow", "width=200,height=100");
        myWindow.document.write("<p>窗口名称为: " + myWindow.name + "</p>");
      }
    </script>
  </head>
  <body>
    <input type="button" value="打开我的窗口" onclick="openWin()" />
  </body>
</html>

运行效果如下

看到这里可能觉得没什么应用场景,那我们再看一个例子

这个是index.html

js 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div>我是主页面</div>
    <script>
      var ifr = document.createElement("iframe");
      ifr.id = "iframeId";
      ifr.src =  "./test.html";
      ifr.style.display = "none";
      document.body.appendChild(ifr);
      ifr.onload = () => {
        ifr.onload = () => {
          ifr.contentWindow.close();
        };
        ifr.contentWindow.location = "about:blank";
      };
    </script>
  </body>
</html>

子页面的逻辑很简单,script只有一行,设置window.name的值为du

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>我是被嵌入的iframe</div>
    <script>
        window.name="du"
    </script>
</body>
</html>     

运行效果如下 我们可以看到,我们在主页面可以拿到嵌入的iframe的name,这个就代表可以跨域进行通信,可以拿到数据了,上面的跨域拿到用户信息的也就可以解释的通了。

总结

  1. 当与第三方公司对接的时候,最好是能拿到对方提供的文档后,再进行开工。如果直接开工,会多做很多的无用功
  2. window.name在某些场景下也可以处理跨域
相关推荐
疯狂踩坑人22 分钟前
结合400行mini-react代码,图文解说React原理
前端·react.js·面试
Mintopia24 分钟前
🚀 共绩算力:3分钟拥有自己的文生图AI服务-容器化部署 StableDiffusion1.5-WebUI 应用
前端·人工智能·aigc
街尾杂货店&27 分钟前
CSS - transition 过渡属性及使用方法(示例代码)
前端·css
CH_X_M39 分钟前
为什么在AI对话中选择用sse而不是web socket?
前端
Mintopia1 小时前
🧠 量子计算对AIGC的潜在影响:Web技术的未来可能性
前端·javascript·aigc
街尾杂货店&1 小时前
css - word-spacing 属性(指定段字之间的间距大小)属性定义及使用说明
前端·css
忧郁的蛋~1 小时前
.NET异步编程中内存泄漏的终极解决方案
开发语言·前端·javascript·.net
水月wwww1 小时前
vue学习之组件与标签
前端·javascript·vue.js·学习·vue
合作小小程序员小小店1 小时前
web网页开发,在线%商城,电商,商品购买%系统demo,基于vscode,apache,html,css,jquery,php,mysql数据库
开发语言·前端·数据库·mysql·html·php·电商
顾安r1 小时前
11.8 脚本网页 塔防游戏
服务器·前端·javascript·游戏·html