vue对嵌入的iframe进行操作记录

本文介绍了如何在Vue应用中处理动态变化的iframeURL,包括解决跨域问题以及操作iframe内部动态生成的DOM元素,如隐藏、删除和追加节点。重点在于确保操作的同源性以避免安全限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

提示:这里可以添加本文要记录的大概内容:

在我们新的需求中,需要用到一个外部的界面用于实现数据可视化监控功能,通过嵌入外部的grafana界面实现。需要对这个iframe的url和内部DOM进行操作。iframe的url通过第一次进入界面,请求后端接口拿到。


提示:以下是本篇文章正文内容,下面案例可供参考

1、iframe的url是动态变化的,我在vue界面怎么拿到这个动态的url

用户在当前iframe界面操作之后,url会随之变化,那我们怎么拿到这个动态的url尼?
首先,需要明白的是,iframe嵌入的界面,我们想拿到里面的动态变化的url,是需要访问iframe的location.href,但是由于同源策略,我们这个地方是跨域的,所以拿不到,第一个问题就是解决跨域,后端通过配置将iframe的地址改为和我们当前项目,同源的。解决跨域。

 <iframe
        ref="iframeRef"
        :src="iframeUrl"
        frameborder="0"
        height="100%"
        onLoad="this.height=100"
        scrolling="auto"
        @load="handleIframeLoad"
      ></iframe>
let iframeRef = ref();

加载完成之后可以通过以下代码拿到动态的url

let getCurIframeUrl = iframeRef.value.contentWindow.location.href;

1、iframe内部的DOM是动态生成的,我如何隐藏DOM或者删除或者后续追加兄弟节点

const handleIframeLoad = () => {
  console.log("监听iframe加载完成");
  if (timer.value) {
    console.log("clear");
    clearInterval(timer.value);
    timer.value = null;
  }
  timer.value = setInterval(() => {
    try {
      // 确保iframe加载完成且同源
      const iframeDoc =
        iframeRef.value.contentDocument ||
        iframeRef.value.contentWindow.document;
      const op = iframeDoc.querySelectorAll(".css-exd1zr"); // 假设你想要删除的按钮有一个唯一的标识符或选择器
      const op_1 = iframeDoc.querySelectorAll(".css-kg0g4j-toolbar-button");

      console.log("op", op);
      console.log("op_1", op_1);

      const btn_get_cur_url = document.createElement("button");
      btn_get_cur_url.className = "css-1krr5n3-toolbar-button";
      btn_get_cur_url.innerHTML = "获取当前页面url";

      const btn_set_url = document.createElement("button");
      btn_set_url.className = "css-1krr5n3-toolbar-button";
      btn_set_url.innerHTML = "将当前查询设置为默认页面";

      btn_get_cur_url.onclick = (data) => {
        getCurUrl();
      };

      btn_set_url.onclick = (data) => {
        setUrl();
      };

      if (op_1[0]) {
        // 删除按钮
        
        op_1[0].style.cssText = "visibility:hidden";
        op_1[0].parentNode.removeChild(op_1[0]);
      }
      if (op[1] && op.length == 4) {
        // 删除按钮
        // op[1].parentNode.removeChild(op[1]);
        setTimeout(() => {
          op[1].style.cssText = "order: 1; visibility: hidden;";
          
          op[0].insertAdjacentElement("beforebegin", btn_get_cur_url);
          op[0].insertAdjacentElement("beforebegin", btn_set_url);
          op[0].parentNode.removeChild(op[0]);
          op[1].parentNode.removeChild(op[1]);
          clearInterval(timer.value);
          timer.value = null;
        });
      }
      setTimeout(() => {
        flag.value = true;
      }, 200);
    } catch (error) {
      // 处理跨域错误或其他异常
      console.error("操作iframe内部DOM元素时发生错误:", error);
    }
  }, 200);
};

onMounted(() => {
  console.log("111")
  if(iframeRef.value) {
    handleIframeLoad()
  }
})

总结

提示:这里对文章进行总结:

对嵌入的iframe进行操作总结,注意的是需要同源,不然拿不到里面的东西!!!

### Vue嵌入 iframe 并调用其内部事件 在 Vue 项目中实现与 `<iframe>` 的交互主要通过 `postMessage` API 来完成跨域安全的消息传递。这种方式允许父页面向子页面发送消息以及接收来自子页面的通知。 #### 创建带有 iframe 的组件结构 定义一个简单的 Vue 组件来加载目标网站: ```vue <template> <div class="container"> <!-- 定义 iframe --> <iframe ref="myIframe" :src="url" @load="onLoad"></iframe> <!-- 操作按钮 --> <button @click="sendMessageToIFrame">Send Message to iFrame</button> </div> </template> <script> export default { data() { return { url: 'https://example.com', // 替换成实际 URL }; }, methods: { onLoad(event) { console.log('iFrame loaded'); window.addEventListener('message', this.receiveMessage); }, sendMessageToIFrame() { const message = { action: "doSomething", payload: {} }; // 获取 iframe DOM 对象并通过 contentWindow 发送消息给子页面 this.$refs.myIframe.contentWindow.postMessage(message, '*'); }, receiveMessage(event) { try { if (event.origin !== 'https://example.com') throw new Error(`Invalid origin ${event.origin}`); switch(event.data.action){ case 'response': alert(JSON.stringify(event.data.payload)); break; default: console.warn('Unknown event received from child frame.'); } } catch(error) { console.error(error.message); } } }, beforeDestroy(){ window.removeEventListener('message', this.receiveMessage); } } </script> ``` 上述代码展示了如何创建一个包含 `<iframe>` 的 Vue 组件,并设置了一个点击按钮用来触发向 iframe 内部发送消息的操作。当 iframe 加载完成后,监听器被注册以便能够接收到由 iframe 返回的信息[^2]。 为了使这段逻辑正常工作,在 iframe 页面也需要相应的处理程序来响应这些请求并将结果反馈回去。假设我们控制着 iframe 所指向的内容,则可以在该页面上添加如下 JavaScript 代码片段: ```javascript window.onmessage = function(e) { var origin = e.origin || e.originalEvent.origin; if(origin === 'https://parent-domain.com'){ // 验证来源域名 let responsePayload = {}; switch(e.data.action){ case 'doSomething':{ // 这里放置具体的业务逻辑 responsePayload = {"status": true}; break; } default:{ console.log('Unrecognized command:', e.data.action); } } parent.postMessage({action:'response',payload:responsePayload},'*'); } }; ``` 这样就可以实现在 Vue 主页和 iframe 子页面之间的双向通讯机制了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值