技术背景
2022年5月,Chrome推出侧边栏API,允许插件在侧边栏加载特定页面,但其灵活性远不及Edge侧边栏(例如不能直接打开ChatGPT、DeepSeek等)。为此,我们尝试在Chrome侧边栏中实现一个真正的"浏览器" ------ Anything Copilot。
核心挑战与解决方案
1. iframe 的"封印":CSP 与 X-Frame-Options
常规方案中,网页或插件若想嵌入其他页面,只能依赖iframe
(webview
仅限App使用)。但现实很残酷:
- X-Frame-Options :通过
DENY
或SAMEORIGIN
限制页面被嵌入 - CSP 策略 :通过
frame-ancestors
控制父级页面来源
绝大多数网站(如GitHub、Twitter)会通过上述机制阻止被嵌入。
安全优先的破解思路:
-
静态资源探测 :
发现部分网站的
/robots.txt
、/sitemap.xml
等非HTML资源未设置CSP策略,通过以下步骤绕过限制:- 在
iframe
中加载允许嵌入的静态资源 - 通过
history.replaceState
修改URL路径 - 使用
document.write
重写页面内容
此方案对约60%的网站有效,但路径探测成本较高。
- 在
-
精准 Header 拦截 :
使用
chrome.declarativeNetRequest
API动态移除Content-Security-Policy
和X-Frame-Options
头,但需严格限制作用范围:javascriptchrome.declarativeNetRequest.updateDynamicRules({ addRules: [{ id: 1, action: { type: "modifyHeaders", responseHeaders: [ { header: "Content-Security-Policy", operation: "remove" }, { header: "X-Frame-Options", operation: "remove" } ] }, condition: { tabIds: [-1], // 仅作用于侧边栏 initiatorDomains: ["your-extension-id"] } }] });
该方案平衡了功能与安全性,最终覆盖了90%以上的网页。
2. 无法逾越的鸿沟:window.top 检测
即便破解了CSP,仍有部分页面因检测window.top
导致崩溃:
javascript
// 页面中的防御代码
if (window.top !== window.self) {
throw new Error("不允许嵌入!");
}
尝试过的方案:
window.top = window
无效Object.defineProperty(window, 'top', { get: () => window })
无效__defineGetter__
,prototype
也无效
成果与反思
基于上述方案,我们最终实现了:
✅ 多标签页管理
✅ 页面缩放/搜索
✅ 地址栏与快捷键支持
项目上线后积累了近万活跃用户,灵活强大的侧边栏给日常的高效学习工作带来了无限可能。
致开发者
如果你:
- 发现更优雅的
window.top
破解方案 - 对Chrome插件的安全边界有深入研究
欢迎在评论区交流!完整技术实现参见 GitHub - Anything Copilot,期待你的Star与PR!