在能加载插件并且自动唤起浏览器后
我们的下一个目标就是可以实现插件与本地进行通信并且传输数据
并且在加载后会提示一个插件已被篡改
https://www.tampermonkey.net/index.php?version=5.1.0&updated=true#installed
我们可以在本地起一个express的服务器,并且篡改掉显示的主页来表明我们注入成功
const express = require("express");
const path = require("path");
const http = require("http");
const { Server } = require("socket.io");
function initLocalServer() {
return new Promise((resolve) => {
const app = express();
app.use(express.static(path.join(__dirname, "/public")));
let server = http.createServer(app);
const io = new Server(server);
io.on("connection", (socket) => {
console.log("a user connected");
socket.on("disconnect", () => {
console.log("user disconnected");
});
});
server.listen(0, () => {
resolve(server.address().port);
});
});
}
exports.initLocalServer = initLocalServer;
这里我们写了一个express服务器,并且监听了socket用于双向传输数据,同时为了解决篡改错误页面的显示,我们可以在public目录写一个自己的页面,然后通过调试找到了在插件的
let e,
t = "version=" + ti.newV + "&ext=" + qe.short_id + "&updated=true";
if (
(ti.first_run
? ((e = "https://www.tampermonkey.net/installed.php?" + t),
(ti.active = !0))
: ((t += "&old=" + ti.oldV),
(e = "https://www.tampermonkey.net/changelog.php?" + t)),
"off" == un.values.notification_showUpdate)
);
我们可以直接替换一下
let e,
t = "version=" + ti.newV + "&ext=" + qe.short_id + "&updated=true";
if (
(ti.first_run
? ((e = window.openPage),
(ti.active = !0))
: ((t += "&old=" + ti.oldV),
(e = window.openPage)),
"off" == un.values.notification_showUpdate)
);
然后提前在该js前引入另外一个js隔离引入变量即可
但是由于express的port是动态的,所以我们需要动态修改,这里我引入了ejs模板
const path = require("path");
const ejs = require("ejs");
const puppeteer = require("puppeteer");
const fs = require("fs");
const templateBase = path.join(__dirname, "./template");
const crxBase = path.join(__dirname, "./tampermonkey_crx");
async function injectCode({ port }) {
const result = await ejs.renderFile(templateBase + "/backgroundInject.js", {
openPage: "127.0.0.1:" + port,
socketURL:"127.0.0.1:" + port
});
fs.writeFileSync(path.join(crxBase, "/backgroundInject.js"), result);
}
async function openBroswer() {
const pathToExtension = crxBase;
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`,
],
});
}
async function init(options) {
await injectCode(options);
await openBroswer();
}
然后编写一个ejs模板
window.openPage=`http://<%= openPage %>`
var socket = io('http://<%= socketURL %>');
socket.send({"Title": "12315645566"})
这样本地的express建立成功并且得到了端口,传给客户端,客户端通过ejs合成一个backgroundInject.js的文件,然后写入到插件目录中,那我们需要提前在background.html
声明一下socket文件以及backgroundInject文件
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="socket.io.min.js"></script>
<script src="backgroundInject.js"></script>
<script src="test.js"></script>
<script src="background.js"></script>
</head>
<body>
</body>
</html>
再通过puppteer来唤起浏览器,那我们编制一下client和server的粘合代码
const server = require("./server/index.js");
const client = require("./client/index.js");
async function init() {
const port=await server.initLocalServer()
client.init({port})
console.log('port',port)
}
init()
exports.init = init;