javascript - Chrome 扩展中的 Web3js 脚本注入
问题描述
我知道对于 Chrome 扩展脚本注入的一般情况,已经有人问过这个问题。我正在询问我的特定 Web3js 用例,看看是否有人有更好的想法,这样我就不需要注入了。
我正在尝试从 Chrome 扩展程序签署以太坊交易。为此,我正在使用 Web3.js。但是,我需要访问 window 变量来实例化 web3。就像是:
if (window.ethereum) {
// current web3 providers
window.web3 = new Web3(window.ethereum);
await window.ethereum.enable();
} else if (window.web3) {
// fallback for older web3 providers
window.web3 = new Web3(window.web3.currentProvider);
} else {
// no web3 provider, user needs to install one in their browser
window.alert('No injected web3 provider detected');
}
由于 Chrome 扩展的 content_scripts 无法访问浏览器的窗口,我不得不同时注入 web3js 代码和使用它的脚本,如下所示:
// inject script.js into the page.
var s = document.createElement('script');
s.src = chrome.runtime.getURL('js/script.js');
s.onload = function() {
this.remove();
};
var w = document.createElement('script');
w.src = chrome.runtime.getURL('third-party/web3.min.js');
w.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(w).appendChild(s);
这工作正常。但是,大多数主要网页都有一个 CSP 来阻止 unsafe-inlines 和 unsafe-evals,这两种方法都发生在这种方法中。因此,我的扩展仅适用于没有此 CSP 的网页。
谁能想到一种更好的方法来实现我想要实现的目标,或者至少是一种绕过 CSP 的方法?
解决方案
有几种解决方案:
使用 chrome.webRequest.onHeadersReceived 事件剥离/修改站点的 CSP 标头,请参阅此示例(它用于不同的标头,因此您将更改名称)。
修改库,使其不使用 eval
在通过web_accessible_resources公开的 iframe 中运行库。该 iframe 将是一个类似于弹出/选项页面的扩展页面,您可以在 manifest.json 中应用您自己的 CSP,更多信息。
因此,内容脚本不会添加
third-party/web3.min.js
,而是会添加一个 iframe:var iframe = document.createElement('iframe'); iframe.src = chrome.runtime.getURL('iframe.html'); document.documentElement.appendChild(iframe);
iframe.html:
<script src="iframe.js"></script> <script src="third-party/web3.min.js"></script>
消息传递会有些复杂。您的页面脚本 (script.js) 可以使用CustomEvent 消息与内容脚本进行通信,而内容脚本又可以使用 chrome.runtime 消息与 iframe 进行通信,例如。或者,直接使用externally_connectable
sender.tab.id
消息传递,以便页面脚本(和网页本身)可以将消息发送到任何扩展脚本(iframe 脚本也会看到它并通过与通过 chrome.xml 获得的自己的标签 ID进行比较来决定是否应该处理它。 tabs.getCurrent)。
推荐阅读
- ios - UIcollectionViewCell内UITableView的动态高度
- python - 线程 Thread-2 中的异常:Python 机器学习错误:Tensorflow 列表超出范围
- ffmpeg - ffmpeg如何在处理后制作uniq签名视频
- c# - C# 进度条最小值未从文本框更新
- linux - Linux命令Cat不归档归档但归档在文件夹中
- indexeddb - indexedDB w/r 到相同的来源和本地文件
- javascript - 如何在现有的身份验证系统中使用 Snapchat 登录工具包?
- php - 如何从 Apache 执行的 php 脚本启动 solr?
- python - 按 Fn 键 Python 3
- php - 为 woocommerce 缺货产品变体显示自定义 div 块