在 Chrome 插件的 content.js中,无法直接访问页面中的 Vue 实例

奇葩需求

需要用Chrome插件将数据赋值给当前页面的表单里,美其名曰帮客户自动填入

头脑风暴

本来是想获取一下当前表单元素,然后一个一个给它赋值,但是input的值好赋啊,其他下拉选择的咋搞

关键是这个当前页面是别人家的,不是我们自己的!!

在控制台倒腾半天,发现人家页面是用Vue写的,UI组件用的elementUI,那form上就会有个Vue的实例,那直接操作这个实例就好了!

在这里插入图片描述

尝试一下

在这里插入图片描述
立刻就能看到效果!!
在这里插入图片描述

在Chrome插件里面尝试一下

// content.js
  let vueInstance = window.document.querySelectorAll('.el-form')[0].__vue__;
  console.log('Vue instance:', vueInstance);

结果

🤣笑死,在Chrome插件的content.js里面根本找不到__vue__
当前页面的window和Chrome插件的content.js里面的window根本不是一个
在这里插入图片描述
换成在background.js也一样找不到o(╥﹏╥)o

ChatGPT提供了2种思路

不得不说ChatGPT还是牛的

  • 思路一

在这里插入图片描述

// In content.js
let vueInstance = document.querySelector('#app').__vue__;
window.postMessage({ type: 'VUE_INSTANCE', data: vueInstance }, '*');

// In the web page
window.addEventListener('message', (event) => {
  if (event.source !== window || event.data.type !== 'VUE_INSTANCE') {
    return;
  }
  let vueInstance = event.data.data;
  console.log('Vue instance:', vueInstance);
});

在这里插入图片描述

  • 思路二

在这里插入图片描述

// In content.js
let script = document.createElement('script');
script.textContent = `
  window.vueInstance = document.querySelector('#app').__vue__;
`;
document.documentElement.appendChild(script);
script.remove();
console.log('Vue instance:', window.vueInstance);

// In the web page
console.log('Vue instance:', window.vueInstance);

  • 思路三

在这里插入图片描述

// In content.js
chrome.runtime.sendMessage({ type: 'GET_VUE_INSTANCE' }, (vueInstance) => {
  console.log('Vue instance:', vueInstance);
});

// In the background page
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'GET_VUE_INSTANCE') {
    let vueInstance = document.querySelector('#app').__vue__;
    sendResponse(vueInstance);
  }
});

在这里插入图片描述

以上思路一我没有办法,因为当前页面是别人的,所以直接pass,思路二和三我试了也是毫无反应!!!

最终解决办法

我基于上面的思路2,就是直接在Chrome插件的content.js里面去注入一段js脚本,在这个js里面去执行,d=但是我不remove,看看能不能找到vue的实例,

const obj = {jobName:'关注一下石马上coding谢谢'}
  let script = document.createElement('script');
  script.textContent = `
  const formData = ${JSON.stringify(obj)};
  console.log('%c [ formData ]-27', 'font-size:13px; background:pink; color:#bf2c9f;', formData)
  
    window.vueInstance = window.document.querySelectorAll('.el-form')[0].__vue__;
    // window.vueInstance.model['jobName'] = '关注一下石马上coding谢谢';
    for (let key in formData) {
      if(window.vueInstance.model.hasOwnProperty(key)) {
        console.log('hasOwnProperty',key)
        window.vueInstance.model[key] = formData[key]
      } else {
        console.log('no Property================>',key)
      }
    }
  `;
  document.documentElement.appendChild(script);

结果竟然成功了O(∩_∩)O哈哈~
在这里插入图片描述
在这里插入图片描述

总结

  • content.js在与网页分离的环境中运行,无法直接访问网页的JavaScript对象,包括Vue实例
  • 可以参考上面ChatGPT的3个思路,我的最终解决办法是根据第2个思路来的,灵活变通了一下,不过也要看具体需求具体分析。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值