写一个Chrome插件
2025年8月21日 11:58
最近一直用的cookie同步插件被禁用了,然后利用chatGPT自己搞了一个
1. 文件清单(直接在项目目录放这些文件)
-
manifest.json
-
background.js
(service worker) -
popup.html
-
popup.js
-
popup.css
(可选,可以直接写在html里面) -
README.md
(可选,使用说明) -
icons
(放展示图标)
将上面的文件放入文件夹中,只保留必要的文件,最终结果如下:
其中icons可以通过网上的免费图标网站自己设计一些
1. manifest.json
{
"manifest_version": 3,
"name": "Multi Cookie Sync",
"version": "1.0",
"description": "Sync all cookies from one site to another with multiple rules.",
"permissions": [
"cookies",
"storage",
"scripting"
],
"host_permissions": [
"<all_urls>"
],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"background": {
"service_worker": "background.js"
}
}
2. background.js
在 Chrome 扩展 (Manifest V3) 里:
- background.js 并不是强制必须的。
- 只有当你需要在后台执行逻辑(比如监听消息、操作 cookie、下载文件等 需要扩展 API 权限 的动作)时,才需要它作为 service worker 存在。
我的需求其实只是将某个网站的cookie同步到开发环境的页面中,绕开SSO登录的逻辑,不需要一些文件的导入导出,或者下载之类的操作,所以我这个文件是空的。
其中监听事件是扩展 API、长生命周期的监听(cookie 变化、tab 更新、消息监听)
比如:
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.type === "EXPORT_COOKIES") {
// 读取 cookie
}
});
注意:该文件中不能访问DOM
3. popup.html
这个就是打开插件后展示的界面
其中代码如下:
<!DOCTYPE html>
<html>
<head>
<title>Multi Cookie Sync</title>
<meta charset="UTF-8">
<style>
body { font-family: sans-serif; width: 360px; padding: 10px; }
input, button { width: 100%; margin: 5px 0; }
label { font-weight: bold; display: block; margin-top: 8px; }
.pair { margin-bottom: 10px; border-bottom: 1px solid #ccc; padding-bottom: 10px; }
.input-actions { display: flex; gap: 10px; }
.input-actions button { flex: 1; }
</style>
</head>
<body>
<h3>添加同步规则</h3>
<input type="text" id="sourceUrl" placeholder="源站 URL,例如 https://a.example.com">
<input type="text" id="targetUrl" placeholder="目标站 URL,例如 https://b.example.com">
<div class="input-actions">
<button id="addPairBtn">添加配对</button>
<button id="clearInputBtn">清空输入</button>
</div>
<h3>配对规则列表</h3>
<div id="pairList"></div>
<button id="syncAllBtn">同步全部 Cookie</button>
<p id="status"></p>
<script src="popup.js"></script>
</body>
</html>
4. popup.js
负责 和用户交互(点按钮、输入网址)
const sourceInput = document.getElementById("sourceUrl");
const targetInput = document.getElementById("targetUrl");
const statusEl = document.getElementById("status");
const pairListEl = document.getElementById("pairList");
function renderPairs(pairs) {
pairListEl.innerHTML = "";
pairs.forEach((pair, index) => {
const div = document.createElement("div");
div.className = "pair";
div.innerHTML = `
<div><strong>源:</strong>${pair.source}</div>
<div><strong>目标:</strong>${pair.target}</div>
<button data-index="${index}" class="deleteBtn">删除</button>
`;
pairListEl.appendChild(div);
});
document.querySelectorAll(".deleteBtn").forEach(btn => {
btn.addEventListener("click", (e) => {
const i = parseInt(e.target.dataset.index);
chrome.storage.sync.get({ sitePairs: [] }, ({ sitePairs }) => {
sitePairs.splice(i, 1);
chrome.storage.sync.set({ sitePairs }, () => renderPairs(sitePairs));
});
});
});
}
document.getElementById("addPairBtn").addEventListener("click", () => {
const sourceUrl = sourceInput.value.trim();
const targetUrl = targetInput.value.trim();
if (!sourceUrl || !targetUrl) {
statusEl.innerText = "请填写完整的源站和目标站 URL";
return;
}
chrome.storage.sync.get({ sitePairs: [] }, ({ sitePairs }) => {
sitePairs.push({ source: sourceUrl, target: targetUrl });
chrome.storage.sync.set({ sitePairs }, () => {
renderPairs(sitePairs);
statusEl.innerText = "已添加规则";
});
});
// ❌ 不再清空输入框(除非用户点击“清空”按钮)
});
document.getElementById("clearInputBtn").addEventListener("click", () => {
sourceInput.value = "";
targetInput.value = "";
});
document.getElementById("syncAllBtn").addEventListener("click", () => {
chrome.storage.sync.get({ sitePairs: [] }, async ({ sitePairs }) => {
for (const pair of sitePairs) {
try {
const cookies = await chrome.cookies.getAll({ url: pair.source });
for (const cookie of cookies) {
await chrome.cookies.set({
url: pair.target,
name: cookie.name,
value: cookie.value,
domain: new URL(pair.target).hostname,
path: cookie.path || "/",
secure: cookie.secure,
httpOnly: cookie.httpOnly,
sameSite: cookie.sameSite || "no_restriction",
expirationDate: cookie.expirationDate || (Date.now() / 1000 + 3600)
});
}
} catch (e) {
console.warn(`同步失败: ${pair.source} ➜ ${pair.target}`, e);
}
}
statusEl.innerText = "所有规则 Cookie 同步完成。";
});
});
chrome.storage.sync.get({ sitePairs: [] }, ({ sitePairs }) => {
renderPairs(sitePairs);
});
// 1. 监听输入变化并存入 storage
sourceInput.addEventListener("input", () => {
chrome.storage.local.set({ currentSourceUrl: sourceInput.value });
});
targetInput.addEventListener("input", () => {
chrome.storage.local.set({ currentTargetUrl: targetInput.value });
});
// 2. 页面打开时恢复输入框内容
chrome.storage.local.get(["currentSourceUrl", "currentTargetUrl"], (data) => {
if (data.currentSourceUrl) sourceInput.value = data.currentSourceUrl;
if (data.currentTargetUrl) targetInput.value = data.currentTargetUrl;
});
document.getElementById("clearInputBtn").addEventListener("click", () => {
sourceInput.value = "";
targetInput.value = "";
chrome.storage.local.remove(["currentSourceUrl", "currentTargetUrl"]);
});
3. 安装和使用
-
将上面文件放到一个文件夹(例如
cookie-syncer
)。 -
打开 Chrome →
chrome://extensions/
。 -
打开右上角「开发者模式」。
-
点击「加载已解压的扩展程序」,选择该文件夹。
-
点击浏览器工具栏扩展图标打开弹窗。
其中目标站就是想要从其同步cookie的网站,比如公司内登录过的SSO网站