iframe 使用注意事项

iframe 使用注意事项

  • src 属性不支持混用 httphttps 协议
  • 使用 @load 来判断 frame 是否加载完毕,相当于 iframe<htmlElement>.onload 方法
  • 获取嵌套页面关联数据必须使用 iframe<htmlElement>.contentWindow 方法,此方法存在跨域限制,需在外层页面配置代理
<template>
  <iframe id="frame" ref="frame" src="http://city.test.uupt.com/#/pages/orderlist" frameborder="0" scrolling="no" @load="loaded"></iframe>
</template>

<script>
  export default {
    methods: {
      loaded() {
        console.clear()
        console.log('Debugger: this.$refs.frame', this.$refs.frame.contentWindow)
      },
    },
  }
</script>

<style lang="scss">
  #frame {
    width: 100%;
    height: 100%;
  }
</style>

iframe 使用注意事项

  • 注意路由跳转混乱

在动态更改 iframesrc 后导致路由跳转混乱,当多次更改 iframe src 属性后,调用 router.go(-1) 并不能实现路由后退一级,而是将 iframe 当作一个窗口文档,调用了 iframewindow.history.go(-1) 而并未更改父页面的路由后退功能

此问题可以通过不使用更改 iframe src 属性的方式来访问具体内容,使用 window.location.replace(url) 更改 iframe 将访问的内容

  • 父子页面通信

两个项目之间相关数据通信,由于浏览器跨域限制,子页面不可直接调用父页面方法,父页面同样不能调用子页面的方法

在确定 iframe 已经加载完毕后,可以使用 window.postMessage() 方法实现跨源数据通信,调用此方法后会在所有页面脚本执行完毕后向目标窗口派发一个 MessageEvent 消息

<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <title>Post Message</title>
  </head>
  <body>
    <div>
      <div id="color">Frame Color</div>
    </div>
    <div>
      <iframe id="child" width="50%" src="http://localhost:3000//test.html" height="50vw" scrolling="auto" frameborder="0"></iframe>
    </div>
    <script type="text/javascript">
      window.onload = function () {
        document.getElementById('child').contentWindow.postMessage('getcolor', 'http://localhost:3000/')
      }
      window.addEventListener(
        'message',
        function (e) {
          const color = e.data
          document.getElementById('color').style.backgroundColor = color
        },
        false
      )
    </script>
  </body>
</html>
<!-- test.html -->
<!DOCTYPE html>
<html>
  <head>
    <style type="text/css">
      html,
      body {
        height: 100%;
        margin: 0px;
      }
      #container {
        widht: 100%;
        height: 100%;
        background-color: rgb(204, 102, 0);
      }
    </style>
  </head>
  <body style="height:100%;">
    <div id="container" onclick="changeColor()">click to change color</div>
    <script type="text/javascript">
      const container = document.getElementById('container')
      window.addEventListener(
        'message',
        function (e) {
          if (e.source != window.parent) return
          const color = container.style.backgroundColor
          window.parent.postMessage(color, '*')
        },
        false
      )
      function changeColor() {
        const color = container.style.backgroundColor
        if (color == 'rgb(204, 102, 0)') {
          color = 'rgb(204, 204, 0)'
        } else {
          color = 'rgb(204,102,0)'
        }
        container.style.backgroundColor = color
        window.parent.postMessage(color, '*')
      }
    </script>
  </body>
</html>

适用于子页面需要调用父页面方法活使用父页面数据的场景,可以使用此方法在子页面向父页面发起通信,让父页面调用该方法,接收父页面相关数据

  • postMessage

postMessage 支持对象传递,但是由于对象传递存在浏览器差异,建议使用字符串传值

为什么不使用 iframe

Why Not Iframe

上一篇:window.postMessage安全地实现跨源通信


下一篇:跨域