前端开发神器:基于Tampermonkey的自动化Cookie同步解决方案
摘要:本文将详细介绍一个基于Vue3+TypeScript开发的Tampermonkey用户脚本项目,该项目实现了跨网页的自动化Cookie管理功能,支持多配置管理、实时同步和智能过滤等特性。
项目背景
在日常开发工作中,我们经常需要在本地开发环境中获取登录状态进行测试,尤其是单点登录系统和微应用架构系统。对于这种需求,有许多成熟的解决方案:
常见解决方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 手动复制粘贴Cookie | 简单直接,无需配置 | 效率低下,容易出错,无法自动更新 | 临时测试 |
| 修改hosts文件同域共享 | Cookie自然共享,无需代码改动 | 需要在后端/nginx配置跨域 | 单机开发 |
| 浏览器扩展自动同步 | 零配置,自动化 | 依赖浏览器 | 浏览器环境 |
现有方案的痛点
当前项目中,使用了vite proxy代理来解决跨域问题,团队采用本地维护一份cookie文件的方式,在项目启动时读取并注入到proxy请求头中。但这种方案存在明显的痛点:
- 更新频繁:单点登录系统的token会定期刷新,需要频繁更新本地cookie文件,导致项目必须重新运行
- 手动维护:每次cookie变化都需要手动复制粘贴,效率低下且容易出错
- 团队协作困难:每个开发者都需要单独维护自己的cookie文件
hosts文件方案
- 需要在后端/nginx配置跨域,且会影响到其他项目的域名解析
- 当每次新起域名时也需要配置跨域和hosts
浏览器扩展方案的优势
- ✅ 零后端改动:完全基于前端实现,不需要后端配合
- ✅ 无需服务器权限:不依赖Nginx等服务器配置
- ✅ proxy友好:完美适配现有的代理开发模式
- ✅ 自动化程度高:Cookie变化时自动同步,无需手动干预
- ✅ 真实数据:直接使用生产环境的真实Cookie数据
- ✅ 团队共享:可以快速在团队内推广使用
核心功能特性
自动化Cookie管理
- 智能提取:从源页面自动提取Cookie数据
- 自动注入:在目标页面自动注入Cookie,无需手动操作
- 实时同步:监听Cookie变化,自动重新注入最新数据
多配置支持
- 独立配置:每个配置项支持独立的源页面和目标页面
- 灵活匹配:支持通配符的URL模式匹配
- 启用控制:可以随时启用或禁用特定配置
高级特性
- Cookie过滤:支持指定需要同步的Cookie,避免不必要的数据传输
- 持久化存储:使用Tampermonkey API实现数据持久化
- 丰富API:提供完整的控制台API用于配置管理和调试
技术架构设计
技术栈选择
{
"frontend": "Vue3 + TypeScript",
"build": "Vite + vite-plugin-monkey",
"runtime": "Tampermonkey",
"storage": "Tampermonkey GM_API"
}
选择这个技术栈的考虑:
- Vue3:提供现代化的开发体验和响应式数据管理
- TypeScript:增强代码的类型安全和可维护性
- Vite:快速的构建工具,配合vite-plugin-monkey专门针对userscript优化
- Tampermonkey API:跨域存储和页面操作的强大支持
核心架构设计
graph TB
A[主入口 main.ts] --> B[AutoCookieManager 协调器]
B --> C[CookieExtractor 提取器]
B --> D[CookieStorage 存储管理器]
B --> E[CookieInjector 注入器]
C --> F[源页面 Cookie 提取]
D --> G[Tampermonkey 存储API]
E --> H[目标页面 Cookie 注入]
G --> I[实时变化监听]
I --> E
B --> J[配置管理系统]
J --> K[多环境配置]
K --> L[URL匹配规则]
🔧 核心模块实现
1. Cookie提取器 (CookieExtractor)
export class CookieExtractor {
private lastCookieString: string = ''
/**
* 从当前页面获取所有cookie字符串
*/
public extractAllCookies(): string {
return document.cookie || ''
}
/**
* 获取当前cookie并检查是否变化
*/
public getCookiesIfChanged(): { cookieString: string; hasChanged: boolean } {
const currentCookies = this.extractAllCookies()
const hasChanged = currentCookies !== this.lastCookieString
if (hasChanged) {
this.lastCookieString = currentCookies
}
return {
cookieString: currentCookies,
hasChanged
}
}
}
- 变化检测机制,避免不必要的存储操作
- 简洁的API设计,易于扩展和测试
2. Cookie存储管理器 (CookieStorage)
export class CookieStorage {
private readonly baseStorageKey = STORAGE_CONFIG.COOKIE_KEY
/**
* 保存cookie字符串到存储
* 只有当cookie发生变化时才保存
*/
public async saveCookies(cookieString: string, configKey: string): Promise<boolean> {
// 检查是否有变化
const isChanged = await this.isCookieChanged(cookieString, configKey)
if (!isChanged) {
return false
}
const data: StoredCookieData = {
cookieString,
source: window.location.hostname
}
const storageKey = this.getStorageKey(configKey)
await GM_setValue(storageKey, data)
return true
}
}
- 基于配置key生成唯一存储标识
- 变化检测机制,提高性能
- 完整的错误处理和调试支持
3. Cookie注入器 (CookieInjector)
export class CookieInjector {
/**
* 将cookie字符串解析并设置到当前页面
*/
public injectCookiesToPage(cookieString: string): void {
const cookies = this.parseCookieString(cookieString)
let successCount = 0
cookies.forEach(cookie => {
try {
this.setCookie(cookie.name, cookie.value, {
path: '/',
domain: this.getCurrentDomain()
})
successCount++
} catch (error) {
console.log(`❌ 设置cookie失败: ${cookie.name}`, error)
}
})
}
}
- 智能Cookie解析,处理各种格式
- 域名适配,确保Cookie能正确设置
- 详细的成功/失败统计
4. 主协调器 (AutoCookieManager)
这是整个系统的核心,负责协调各个模块:
export class AutoCookieManager {
public async init(): Promise<void> {
// 从存储中加载配置并与默认配置合并
await this.loadAndMergeConfigs()
// 根据当前页面决定行为
const currentUrl = window.location.href
const matchedConfig = this.findMatchingConfig(currentUrl)
if (matchedConfig) {
if (this.isSourceUrl(currentUrl, matchedConfig.sourceUrl)) {
// 源页面:开始抓取cookie
await this.startCookieExtraction(matchedConfig)
} else if (this.isTargetUrl(currentUrl, matchedConfig.targetUrls)) {
// 目标页面:注入cookie
await this.startCookieInjection(matchedConfig)
}
}
}
}
URL匹配机制
项目实现了强大的URL匹配机制,支持通配符模式:
private matchUrl(url: string, patterns: string[]): boolean {
return patterns.some(pattern => {
// 处理通配符模式
if (pattern === '*') {
return true // 匹配所有URL
}
// 将模式转换为正则表达式
const regexPattern = pattern
.replace(/\./g, '\\.') // 转义点号
.replace(/\+/g, '\\+') // 转义加号
.replace(/\(/g, '\\(') // 转义括号
.replace(/\)/g, '\\)')
.replace(/\*/g, '.*') // * 匹配任意字符
const regex = new RegExp(`^${regexPattern}$`, 'i')
return regex.test(url)
})
}
支持的匹配模式:
*- 匹配任意字符https://example.com/*- 匹配该域名下所有页面http://localhost:*/*- 匹配本地所有端口https://test-*.example.com/*- 匹配所有测试子域名
实时同步机制
项目的一大亮点是实现了跨页面的实时Cookie同步:
private addCookieStorageListener(config: ConfigItem): void {
const storageKey = `${STORAGE_CONFIG.COOKIE_KEY}_${config.key}`
const listenerId = GM_addValueChangeListener(storageKey, async (key: string, oldValue: any, newValue: any, remote: boolean) => {
if (remote && newValue) {
console.log(`🔄 检测到配置 ${config.key} 的cookie存储发生变化,重新注入...`)
// 获取新的cookie字符串并重新注入
const cookieData = newValue
if (cookieData && cookieData.cookieString) {
this.injector.injectCookiesToPage(cookieData.cookieString)
console.log(`✅ 已重新注入配置 ${config.key} 的最新cookie`)
}
}
})
// 保存监听器ID用于后续清理
this.cookieChangeListeners.set(config.key, listenerId)
}
实现原理:
- 使用Tampermonkey的
GM_addValueChangeListener监听存储变化 - 当其他页面更新Cookie时,目标页面自动接收变化通知
- 实时重新注入最新的Cookie数据
🛠️ 配置管理系统
配置数据结构
interface ConfigItem {
key: string // 唯一标识符
name?: string // 配置名称(可选,用于显示)
sourceUrl: string // 源URL(抓取cookie的页面)
targetUrls: string[] // 目标URL列表(注入cookie的页面)
enabledCookies: string[] // 启用的cookie列表(空数组表示所有cookie)
enabled?: boolean // 是否启用此配置(默认true)
}
API接口设计
项目提供了完整的控制台API:
// 📋 配置管理
autoSettingCookieScript.getConfigs() // 查看所有配置
autoSettingCookieScript.addConfig(configItem) // 添加配置
autoSettingCookieScript.updateConfig(key, updates) // 更新配置
autoSettingCookieScript.removeConfig(key) // 删除配置
// 🔧 核心功能
autoSettingCookieScript.clearAllCookieData() // 清除所有存储数据
autoSettingCookieScript.clearPageCookies() // 清除当前页面Cookie
// 🐛 调试工具
autoSettingCookieScript.showStoredCookies(configKey) // 查看存储的Cookie
autoSettingCookieScript.showStorageInfo() // 查看存储信息
使用案例
场景1:本地开发环境Cookie同步
// 添加开发环境配置
await autoSettingCookieScript.addConfig({
key: "local-dev",
name: "本地开发环境",
sourceUrl: "https://prod-admin.example.com/*",
targetUrls: [
"http://localhost:3000/*",
"http://localhost:8080/*",
"http://127.0.0.1:*/*"
],
enabledCookies: ["access_token", "refresh_token", "user_id"]
})
场景2:多环境Cookie管理
// 测试环境
await autoSettingCookieScript.addConfig({
key: "test-env",
sourceUrl: "https://auth.test.example.com/*",
targetUrls: ["https://app.test.example.com/*"],
enabledCookies: [] // 同步所有cookie
})
// 预发布环境
await autoSettingCookieScript.addConfig({
key: "staging-env",
sourceUrl: "https://auth.staging.example.com/*",
targetUrls: ["https://app.staging.example.com/*"],
enabledCookies: []
})
工作流程
sequenceDiagram
participant SP as 源页面
participant TM as Tampermonkey存储
participant TP as 目标页面
participant User as 用户
User->>SP: 访问源页面
SP->>SP: 提取Cookie
SP->>TM: 存储Cookie数据
User->>TP: 访问目标页面
TP->>TM: 读取Cookie数据
TP->>TP: 注入Cookie到页面
TP->>TM: 监听存储变化
Note over SP,TP: 实时同步
SP->>TM: Cookie发生变化
TM->>TP: 通知变化
TP->>TP: 重新注入新Cookie
项目亮点
1. 模块化架构
- 清晰的职责分离,每个模块专注单一功能
- 易于测试和维护
- 良好的扩展性
2. 智能化特性
- 自动检测Cookie变化,避免不必要的操作
- 智能URL匹配,支持复杂的匹配规则
- 实时同步机制,提供无缝的用户体验
3. 用户友好
- 丰富的控制台API,便于调试和管理
- 详细的日志输出,便于问题排查
- 灵活的配置选项,适应不同使用场景
4. 安全性考虑
- Cookie过滤机制,只同步必要的数据
- 域名适配,确保Cookie安全设置
- 错误处理,避免脚本崩溃
未来规划
- UI界面:开发可视化的配置管理界面
- Cookie加密:增加Cookie数据的加密存储
- 批量操作:支持批量导入/导出配置
- 更多匹配规则:支持更复杂的URL匹配模式
- 性能优化:进一步优化内存使用和执行效率
总结
这个项目展示了如何使用现代化的前端技术栈来开发Tampermonkey用户脚本,主要技术要点包括:
- TypeScript类型系统的应用,提高代码质量
- 模块化设计的实践,增强代码可维护性
- 事件驱动架构的使用,实现实时同步
- 配置驱动开发的思想,提高灵活性
- Tampermonkey API的深度使用,充分利用平台能力
Proxy环境下的技术考虑
在现代前端开发中,很多团队使用proxy代理来解决跨域问题:
// 典型的开发环境proxy配置
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'https://prod-api.example.com',
changeOrigin: true,
secure: true
}
}
}
})
在这种架构下,Auto Cookie方案的技术优势特别明显:
- 绕过CORS限制:Tampermonkey脚本可以访问任意域名,不受同源策略限制
- 保持开发流程:不需要修改现有的proxy配置,保持原有开发习惯
- 真实环境测试:直接使用生产环境Cookie,确保测试的真实性
- 零侵入性:对现有项目架构零影响,可以随时启用或禁用
通过这个项目,我们不仅解决了proxy环境下的登录状态管理问题,也探索了在现代前端开发环境中使用Tampermonkey的最佳实践。
结语
Auto Cookie项目是一个实用的开发工具,它展示了如何将现代前端技术与浏览器扩展开发相结合,创造出既实用又优雅的解决方案。通过智能化的Cookie管理,显著提升了开发效率,减少了重复性的手动操作。
如果你也在寻找类似的解决方案,或者对Tampermonkey脚本开发感兴趣,欢迎参考这个项目的设计思路和实现方案。
项目地址:GitHub - auto-cookie
作者:李二牛
技术栈:Vue3 + TypeScript + Vite + Tampermonkey
如果这篇文章对你有帮助,欢迎点赞、收藏和分享!有任何问题也欢迎在评论区讨论。