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在某些场景下也可以处理跨域
相关推荐
_AaronWong1 天前
Electron 实现仿豆包划词取词功能:从 AI 生成到落地踩坑记
前端·javascript·vue.js
cxxcode1 天前
I/O 多路复用:从浏览器到 Linux 内核
前端
用户5433081441941 天前
AI 时代,前端逆向的门槛已经低到离谱 — 以 Upwork 为例
前端
JarvanMo1 天前
Flutter 版本的 material_ui 已经上架 pub.dev 啦!快来抢先体验吧。
前端
恋猫de小郭1 天前
AI 可以让 WIFI 实现监控室内人体位置和姿态,无需摄像头?
前端·人工智能·ai编程
哀木1 天前
给自己整一个 claude code,解锁编程新姿势
前端
程序员鱼皮1 天前
GitHub 关注突破 2w,我总结了 10 个涨星涨粉技巧!
前端·后端·github
UrbanJazzerati1 天前
Vue3 父子组件通信完全指南
前端·面试
是一碗螺丝粉1 天前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain
wuhen_n1 天前
双端 Diff 算法详解
前端·javascript·vue.js