- 作者:老汪软件技巧
- 发表时间: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 文件并查看思维导图,甚至可以离线运行。