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在某些场景下也可以处理跨域
相关推荐
weixin_493503674 小时前
Vue3 前端生成 PDF:会员证书与活动签到表的三种打印方案与踩坑记录
前端·pdf·状态模式
尾善爱看海8 小时前
前端算法与手写题集
前端·算法
徐小夕8 小时前
JitWord 4.0 万字分享:从协同工具到AI Word操作系统,聊聊3年产品创业史
前端·vue.js·后端
萧鼎9 小时前
Python 高性能Web框架神器 FastAPI:自动生成API文、基于Pydant、异步请求处理全搞定
前端·python·fastapi
IT_陈寒10 小时前
Redis误用keys命令把生产环境搞崩了,血的教训
前端·人工智能·后端
计算机魔术师10 小时前
5000亿估值冲刺科创板,DeepSeek 为何急着上市?
前端
我血条子呢10 小时前
前端解析word方案
前端·word
kyriewen11 小时前
我用 AI 写完一个需求后才发现,最难的不是 prompt,而是验收
前端·程序员·ai编程
申行11 小时前
Vue 3 + DYMO Connect Framework 实战:从标签模板到打印服务的完整实现
前端
两只羊ovo11 小时前
Vue 3 + DeepSeek 流式输出实战:从“干等”到“打字机”体验
前端·vue.js