• 作者:老汪软件技巧
  • 发表时间:2024-09-06 04:01
  • 浏览量:

背景介绍

随着Chrome拓展升级到V3版本,谷歌又在慢慢的收紧权限,现在已经不允许在插件中运行远程代码,这也导致了一些问题。比如最近利用浏览器插件,获取页面的数据,然后把关键词做成一个思维导图,生成HTML保存下来,这时候借助了第三方插件jsMind,在生成的HTML页面的时候,通过js拼接代码在页面中嵌入jsMind的依赖,如下所示:

// jsMind 库的 CDN 路径 
const jsMindCSS = '' 
const jsMindJS = '' 
const jsMindDraggableJS = '' 
const docToImageJS = '' 
const screenshotJS = ''

但是Chrome认为这是远程代码,在插件审核的时候给打回了,这就很尴尬,这时候该怎么办呢?

解决思路

如果远程代码不允许的话,那么只能考虑从本地引入的方式,但是这时候还会有一些问题,浏览器中的 Chrome 插件不支持直接访问文件系统,那么这里我直接将所有外部的 JS 和 CSS 资源文件打包到 Chrome 插件的扩展包中,并通过 Chrome 插件的web_accessible_resources配置访问这些资源文件。

1、将资源文件包含在 Chrome 插件中

首先在插件的根目录下创建一个jsmind文件夹,将所有依赖的资源文件(CSS 和 JS 文件)放到插件的 jsmind 目录中

/jsmind/jsmind.css
/jsmind/jsmind.js
/jsmind/jsmind.draggable-node.js
/jsmind/dom-to-image.min.js
/jsmind/jsmind.screenshot.js

2、配置 manifest.json

在 manifest.json 中配置 web_accessible_resources,确保 HTML 文件生成后能正确访问这些本地资源。

{
  "name": "Mind Map Chrome Plugin",
  "version": "1.0",
  "manifest_version": 3,
  "web_accessible_resources": [
    {
      "resources": [
        "jsmind/jsmind.css",
        "jsmind/jsmind.js",
        "jsmind/jsmind.draggable-node.js",
        "jsmind/dom-to-image.min.js",
        "jsmind/jsmind.screenshot.js"
      ],
      "matches": [""]
    }
  ]
}

远程浏览技术规范__谷歌浏览器手机版能安装插件吗

3、动态获取资源的路径

使用 chrome.runtime.getURL()这个 API 可以生成相对路径的 URL,指向 Chrome 插件的本地资源。我们可以通过这个方法引用 CSS 和 JS 文件,而不依赖于外部 CDN。修改后的获取文件的代码如下所示:

// 相对路径指向插件中的本地资源 
const jsMindCSSUrl = chrome.runtime.getURL('jsmind/jsmind.css'); 
const jsMindJSUrl = chrome.runtime.getURL('jsmind/jsmind.js'); 
const jsMindDraggableJSUrl = chrome.runtime.getURL('jsmind/jsmind.draggable-node.js'); 
const docToImageJSUrl = chrome.runtime.getURL('jsmind/dom-to-image.min.js'); 
const screenshotJSUrl = chrome.runtime.getURL('jsmind/jsmind.screenshot.js');

4、优化代码

这时候会有一个问题,不知道大家有没有关注到:

chrome.runtime.getURL()可以动态获取资源的路径,可以确保生成的 HTML 文件能够正确加载本地资源并离线运行。但是这种方法只有在插件环境中是有效的,生成的文件发送给别人是无法打开的,一旦插件卸载了,或者插件的ID改变了,HTML中的引入路径就失效了

为了解决这个问题,我们可以通过 fetch 或者类似的方法获取资源文件的内容(如 CSS 和 JS 文件),然后将这些内容直接嵌入到生成的 HTML 文件中。这种方式可以确保生成的文件完全独立,可以发送给别人,并且在离线情况下运行。

// 使用 fetch 获取文件内容 
const jsMindCSS = await fetch(jsMindCSSUrl).then(res => res.text()); 
const jsMindJS = await fetch(jsMindJSUrl).then(res => res.text()); 
const jsMindDraggableJS = await fetch(jsMindDraggableJSUrl).then(res => res.text()); 
const docToImageJS = await fetch(docToImageJSUrl).then(res => res.text()); 
const screenshotJS = await fetch(screenshotJSUrl).then(res => res.text());

代码设计思路:

使用 chrome.runtime.getURL() 动态获取 Chrome 插件中资源的路径。使用 fetch() 方法从这些路径读取文件的内容(如 CSS 和 JS 文件)。将这些文件内容以 内联 方式嵌入到生成的 HTML 文件中,而不是通过外部链接引用。最终生成的 HTML 文件是完全独立的,别人收到文件后也能正常运行。

整体代码:

import { saveAs } from 'file-saver';
// 动态获取资源文件路径
const jsMindCSSUrl = chrome.runtime.getURL('jsmind/jsmind.css');
const jsMindJSUrl = chrome.runtime.getURL('jsmind/jsmind.js');
const jsMindDraggableJSUrl = chrome.runtime.getURL('jsmind/jsmind.draggable-node.js');
const docToImageJSUrl = chrome.runtime.getURL('jsmind/dom-to-image.min.js');
const screenshotJSUrl = chrome.runtime.getURL('jsmind/jsmind.screenshot.js');
// 通过 fetch 读取资源文件内容,并生成 HTML 文件
async function generateMindMap(nodeArray, name) {
  // 使用 fetch 获取文件内容
  const jsMindCSS = await fetch(jsMindCSSUrl).then(res => res.text());
  const jsMindJS = await fetch(jsMindJSUrl).then(res => res.text());
  const jsMindDraggableJS = await fetch(jsMindDraggableJSUrl).then(res => res.text());
  const docToImageJS = await fetch(docToImageJSUrl).then(res => res.text());
  const screenshotJS = await fetch(screenshotJSUrl).then(res => res.text());
  // 生成 HTML 文件内容,内嵌 CSS 和 JS
  const htmlContent = `
    
    
        
        jsMind Example
        
    
    
        
`
; // 创建 Blob 对象并保存文件 const blob = new Blob([htmlContent], { type: 'text/html;charset=utf-8' }); saveAs(blob, `${name}.html`); } export default generateMindMap;

通过上述的代码将所有的 CSS 和 JS 文件内容都被嵌入到了生成的 HTML 文件中,这样生成的 HTML 文件不依赖外部的文件,完全独立。最终生成的 HTML 文件会包含所有的必要资源,不再依赖插件环境,任何人都可以打开该 HTML 文件并查看思维导图,甚至可以离线运行。