前言:

Google Chrome商店目前已经停止Manifest V2版本的扩展程序的上架,已上架的V2扩展仍可提交。虽然谷歌说2023年1月才将彻底关停V2,但目前已有部分开发者收到邮件要求一个月内升级v3并提交,否则会被下架处理。

所以需要尽快升级,一起来看下manifest V3做了哪些改动吧。

1.Service worker替换backgroud page/js

  1. 在 manifest.json 中替换background.pagebackground.scripts替换为service_worker​​​​​​​
    "background": {
        "service_worker": "js/background.js"
     },
  2. background.persistent从 manifest.json 中删除。 

  3. 使用Service worker编写代码。只能注册事件侦听器,不能持续运行。 举个例子:

// 错误用法
const count = 1
chrome.runtime.onMessage.addListener(({ type, name }) => {
  if (type === "add-count") {
    count++;
  }
});


// 迁移方案
chrome.runtime.onMessage.addListener(({ type, name }) => {
  const count = await chrome.storage.local.get(['count']);
  if (type === "add-count") {
    count++;
    chrome.storage.local.set({'count': count})
  }
});

   注意:执行环境中是不可以使用localStorage、window变量的

2.使用新的declarativeNetRequest来修改请求  

      在manifestv2扩展中,如果想要修改请求的headers我们会这样做:

chrome.webRequest.onBeforeSendHeaders.addListener(
  function(info) {
    const headers = info.requestHeaders; 
    for (var i = headers.length - 1; i >= 0; --i) {
      var header = headers[i];
      var isRemoveKey = header.name.toLowerCase() === 'foo';
      headers.splice(i, 1); // Remove header 
    }
    return { requestHeaders: headers };
  },
  {
    urls: ['https://a.b.net/api/*'],
  },
  ['blocking', 'requestHeaders', chrome.webRequest.OnBeforeSendHeadersOptions.EXTRA_HEADERS].filter(Boolean)
);

      在manifest V3中,要实现以上功能迁移方案为 declarativeNetRequest API。通过指定声明性规则来阻止或修改网络请求。这使扩展程序可以修改网络请求,而无需拦截它们并查看其内容,从而提供更多隐私。 

      首先需要在manifest中添加对应权限和指定静态规则集,

{
  "name": "My extension",
  ...

  "declarative_net_request" : {
    "rule_resources" : [
       {        
        "id": "ruleset_1",
        "enabled": true,
        "path": "rules_1.json"
       }
    ]
  },
  "permissions": [
    "declarativeNetRequest",  
    "declarativeNetRequestFeedback",
    ...
  ],
  ...
}

    然后在目录下新建rules_1.json, 我们还是以修改Headers为例

[
  {
    "id": 1,
    "priority": 1,
    "condition": {
      "regexFilter": "https://XXX.XXX.XXX/api/*",
      "resourceTypes": [
        "xmlhttprequest"
      ]
    }, 
    "action": { 
      "type": "modifyHeaders",
      "requestHeaders": [
        {
          "header": "h1",
          "operation": "set",
          "value": "v4"
        },
        {
          "header": "foo",
          "operation": "remove"
        }
      ]
    }
  }
]

 与webRequest API的比较:

  1. ​使用 declarativeNetRequest API 阻止或修改请求一般不需要主机declarativeNetRequest权限
  2. 因为请求不会被扩展进程拦截,所以 declarativeNetRequest 不需要扩展有后台页面,从而减少内存消耗。
  3. ​​​​​​ 在决定请求是被阻止还是重定向时,declarativeNetRequest API 的优先级高于 webRequest API,因为它允许同步拦截。
  4. webRequest API 更灵活,因为允许以编程方式进行修改。

  API更多细节请见:declarativeNetRequest API

3.不再允许执行远程代码,只可以执行插件包内的脚本/CSS

    Manifest V3 的一个关键安全改进是扩展不能加载远程代码,如 JavaScript 或 Wasm 文件。比如:cdn上的脚本、从服务器获取的 JavaScript 文件、 从后端获取的js字符串。 具体来说,所有脚本都必须包含在扩展包中。

  在 Manifest V2 中,可以使用tabs.executeScript()的属性和属性来执行任意代码字符串。Manifest V3 不允许任意代码执行。为了适应这种需求,扩展开发者可以使用该scripting.executeScript()方法注入静态文件或函数 (注意: 没有code参数了)

   使用方式:

{
  "manifest_version": 3,
  "permissions": ["scripting"],
  ...
}
// Manifest V2

// background.js
...
chrome.tabs.executeScript({
  file: 'content-script.js'
});
...

// content-script.js
...
alert('File test alert');
...


// Manifest V3

// background.js
...
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();

chrome.scripting.executeScript({
  target: {tabId: tab.id},
  files: ['content-script.js']
});
...

// content-script.js
...
alert('File test alert');
...

   这个修改说实话影响太大了,直接影响了像是油猴这种扩展的核心功能。暂不清楚谷歌到时候会不会放宽一些限制,目前来看不太现实

4.其他修改点​​​​​​​​​​​​​​

  1. 如果有主机权限,需要将主机权限移动到host_permissions manifest.json 中的字段中。
     "host_permissions": [ 
        "<all_urls>"
      ],
  2. browser_action和page_action 统一为了action字段,同样的chrome.browserAction还是chrome.pageAction统一为了chrome.action API

     "action": {
        "default_popup": "pages/popup.html",
        "default_icon": "icons/icon-logo.png",
        "default_title": "Popup"
      },

5.彻底移除的API

  • chrome.extension.getExtensionTabs()
  • chrome.extension.getURL()
  • chrome.extension.lastError
  • chrome.extension.onRequest
  • chrome.extension.onRequestExternal
  • chrome.extension.sendRequest()
  • chrome.tabs.getAllInWindow()
  • chrome.tabs.getSelected()
  • chrome.tabs.onActiveChanged
  • chrome.tabs.onHighlightChanged
  • chrome.tabs.onSelectionChanged
  • chrome.tabs.sendRequest()
  • chrome.tabs.Tab.selected

   

参考地址:Google Chrome Extension官方文档

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐