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在某些场景下也可以处理跨域
相关推荐
虾球xz7 分钟前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇12 分钟前
HTML常用表格与标签
前端·html
疯狂的沙粒16 分钟前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员32 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐34 分钟前
前端图像处理(一)
前端
程序猿阿伟41 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒43 分钟前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪1 小时前
AJAX的基本使用
前端·javascript·ajax
力透键背1 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript
程楠楠&M1 小时前
node.js第三方Express 框架
前端·javascript·node.js·express