Skip to content

插件实现机制

1. 插件运行机制

1.1 运行环境

项目本身是使用的capacitor开发的,而capacitor是基于Android的webview,所有运行环境就是浏览器环境,但为了一定的安全考虑(比如页面不被破坏)插件在受限的环境中执行,只有部分 JavaScript 全局对象可用。safeRunContext 通过代理 window 对象,仅允许访问 SetMapfetch 等安全 API,避免插件访问敏感数据。

ts
//只有定义的才可在插件中访问
  const whitelist = {
    Set: true,
    Map: true,
    navigator: true,
    console: true,
    fetch: true,
    XMLHttpRequest: true,
    FormData: true,
    DOMParser: true,
    Promise: true,
    String: true,
    Array: true,
    unescape: true,
    decodeURI: true,
    decodeURIComponent: true,
    encodeURI: true,
    encodeURIComponent: true,
    URL: true,
    Blob: true,
    JSON: true,
    eval: true,
    Object: true,
  }

5.2 安全执行

插件代码通过 safeRunScript 运行,该函数使用 Function 创建新的作用域,并在 with (IConfig.safeWindow) 内部执行插件代码,确保代码只能访问白名单内的变量。

5.3 依赖注入

插件通过 fnOption.require 引入系统提供的功能,fnOption.module 访问插件的导出内容,fnOption.env 读取系统环境变量。 由于运行环境本质是浏览器环境,那么在使用fetch请求时会存在部分请求头无法设置的问题,所有项目提供了require来使用一些系统函数来处理,插件中可直接使用以下代码,如:

ts
//使用的是CapacitorHttp,具体可参考CapacitorHttp的文档
const Http = require("http");
//代理图片地址,返回图片base64
const proxyImg = require('proxyImg')

这里是全部的require函数:

ts
{
    http: CapacitorHttp,
    CryptoJS: CryptoJS,
    analysis: analysis,
    proxyImg: proxyImg
},

5.4 生命周期

插件在被加载或软件启动时,会自动执行插件函数的函数体,并将插件的模块导出(module.exports)作为插件的实例。

插件实例和插件中的数据会在软件的生命周期内持续存在,直至软件或者插件被卸载。