chrome extensions mv3与mv2比较 & 执行eval

背景

老的扩展项目使用的是mv2版本的API,计划升级mv3版本的时候遇到了下面的问题,这些问题对老项目的影响非常大,所以这里特此记录一下。

1、mv3版本与mv2版本之间的一些区别

这里主要说明的就是mv3版本background.js关于DOM的操作和执行任意字符串js的区别。解决DOM交互和任意JS代码的执行就能完成大部分功能了

  1. mv3的background.js禁用了DOM元素交互(document & window等对象不可用)
    在这里插入图片描述
  2. ▶mv3禁止在background.js执行任意字符串的js(new Function & eval不可用)
    在这里插入图片描述
  3. mv3禁止使用XMLHttpRequest请求改为使用fetch请求(本质上也是background.js禁用对象后不支持了)
    在这里插入图片描述在这里插入图片描述

2、解决mv3版本DOM交互 & JS执行问题

因为mv3不仅在background.js禁用了以上功能,也在content禁用了以上功能。所以说现在mv3版本的扩展不再执行未经扩展审核的js以及相关库的不安全脚本。但是,扩展又不能完全的禁用掉js的执行,所以有了下面在content引入eval5来帮助执行一些js代码和完成解析DOM的操作。

为什么要在conten引入而不是直接在background引入?

因为background.js中禁用了document & window等对象,引入之后服务工作进程就会加载失败了。

2.1、关于引入eval5

eval5-marter
打开上面链接访问github,下载并查看关于eval5的使用。并在manifest.json引入eval5的js库
https://github.com/bplok20010/eval5/blob/master/docs/umd/eval5.min.js
在这里插入图片描述

需要说明的一点是,eval5只支持完成ES5语法,不支持ES6语法,比如箭头函数、let、const等。如果想要写ES6语法,需要使用其他库(babel)将ES6转为ES5语法使用,这里不是重点也不做介绍!

2.2、关于在background.js执行script脚本

https://developer.chrome.com/docs/extensions/reference/scripting/
为了避免跨域一般是在background执行一些跨域的请求(如获取一些html文本、请求一些跨域api),但是请求之后通过message反复的进行消息通信进行数据处理无疑是非常麻烦的!所以引用了mv3支持的chrome.scripting API执行一些内容脚本,完成后将内容直接返回,大大降低了通信成本和代码复杂度。
附部分关键代码,脚本执行 & eval5执行

/**
 * background向content-script执行方法脚本
 * @param {*} tabId 在指定的tabId执行脚本
 * @param {*} func 需要执行脚本的方法名
 * @param {*} args 脚本方法的参数
 * @param {*} callback 执行成功,返回结果的回调
 */
function executeScriptFunc(tabId, func, args, callback) {
    
    
  chrome.scripting.executeScript({
    
    
    target: {
    
    tabId: tabId},
    func: func,
    args: args
  }, (resultArr) => {
    
    
    if (callback && resultArr && resultArr.length > 0) {
    
    
      // 只取主帧的返回结果
      callback(resultArr[0].result)
    }
  })
}
function testEval5() {
    
    
   let interpreter = new eval5.Interpreter(window);
  // let result = interpreter.evaluate(
  //     `   var a = 4;
  //         var b = 3;
  //         var sum = a+b;
  //         console.log('a+b=', sum)
  //     `
  // , {console: console, window: window, document: document})
  // ###
  let result = interpreter.evaluate(
      `   var a = 4;
          var b = 3;
          var sum = a+b;
          console.log('a+b=', sum);
          sum;
      `)
  console.log('eval5执行结果:', result) 
}
function testParseHtml(htmlData) {
    
    
  let dom = new DOMParser()
  let doc = dom.parseFromString(htmlData, 'text/html')
  console.log('doc:', doc?.title)
  return doc?.title
}
// 执行eval5调用
executeScriptFunc('your tabId', testEval5, [], (execResult) => {
    
    
  console.log(execResult)
})

// 解析html调用
fetch('https://www.baidu.com').then(rsp => {
    
     
    return rsp.text()
}).then(html => {
    
    
    executeScriptFunc('your tabId', testParseHtml, [html], (execResult) => {
    
    
        console.log('执行结果返回:', execResult)
        sendResponse('ok')
    })
})

eval5执行结果
在这里插入图片描述

HTML解析执行结果
在这里插入图片描述

3、background执行fetch调用URL

js fetch使用 & 参数

fetch('https://www.baidu.com').then(rsp => {
    
     
  return rsp.text()
}).then(html => {
    
    
  console.log(html)
})

参考

谷歌来了也不好使!谁说Chrome插件v3中不能使用eval?

猜你喜欢

转载自blog.csdn.net/dongzi_yu/article/details/128441466