字
字节笔记本
2026年2月22日
沉浸式翻译扩展 Background.js 源码解析
本文介绍沉浸式翻译(Immersive Translate)浏览器扩展的背景脚本(background.js)实现。这是一个已归档的开源项目,提供了双语对照网页翻译功能,支持 Chrome、Firefox 等主流浏览器。
项目概述
沉浸式翻译扩展的核心架构采用典型的浏览器扩展设计模式,分为以下几个主要组件:
- Background Script - 后台脚本,处理浏览器事件和跨页面通信
- Content Script - 内容脚本,直接操作网页 DOM 进行翻译
- Popup - 弹出窗口,提供快速设置界面
- Options Page - 选项页面,完整的配置管理
Background.js 核心功能解析
1. 错误处理与工具函数
javascript
"use strict";
// 避免在控制台输出 "Receiving end does not exist" 错误
function checkedLastError() {
chrome.runtime.lastError
}2. MIME 类型追踪
后台脚本通过 webRequest API 监听响应头,获取页面的 MIME 类型,用于后续 PDF 文件检测:
javascript
var tabToMimeType = {}
chrome.webRequest.onHeadersReceived.addListener(function(details) {
if (details.tabId !== -1) {
let contentTypeHeader = null
for (const header of details.responseHeaders) {
if (header.name.toLowerCase() === 'content-type') {
contentTypeHeader = header
break
}
}
tabToMimeType[details.tabId] = contentTypeHeader && contentTypeHeader.value.split(';', 1)[0]
}
}, { urls: ['*://*/*'], types: ['main_frame'] }, ['responseHeaders']);3. 消息通信机制
Background 脚本作为消息中转站,处理来自 Content Script 的各类请求:
| Action | 功能说明 |
|---|---|
getMainFramePageLanguageState | 获取主框架页面语言状态 |
getMainFrameTabLanguage | 获取原始标签页语言 |
setPageLanguageState | 更新页面语言状态并刷新右键菜单 |
openOptionsPage | 打开选项页面 |
detectTabLanguage | 检测标签页语言 |
getTabHostName | 获取当前标签页主机名 |
getTabMimeType | 获取标签页 MIME 类型 |
detectLanguage | 检测文本语言 |
4. 右键菜单管理
动态创建和管理浏览器右键菜单,根据翻译状态切换菜单文本:
javascript
function updateContextMenu(pageLanguageState = "original") {
let contextMenuTitle
if (pageLanguageState === "translated") {
contextMenuTitle = chrome.i18n.getMessage("btnRestore")
} else {
const targetLanguage = twpConfig.get("targetLanguage")
contextMenuTitle = chrome.i18n.getMessage("msgTranslateFor", twpLang.codeToLanguage(targetLanguage))
}
// 创建或更新菜单...
}5. 扩展安装与更新处理
javascript
chrome.runtime.onInstalled.addListener(details => {
if (details.reason == "install") {
// 首次安装,打开选项页面
chrome.tabs.create({ url: chrome.runtime.getURL("/options/options.html") })
} else if (details.reason == "update") {
// 版本更新,清理翻译缓存
twpConfig.onReady(async () => {
translationCache.deleteTranslationCache()
// 处理快捷键配置迁移...
})
}
})6. 图标状态管理
根据页面翻译状态和浏览器主题动态更新扩展图标:
javascript
function getSVGIcon() {
const svgXml = \`...\` // SVG 模板
let svg64
if (pageLanguageState === "translated" && twpConfig.get("popupBlueWhenSiteIsTranslated") === "yes") {
// 翻译完成状态 - 蓝色图标
svg64 = svgXml.replace(/\\\$(\\\(fill\\\-opacity\\\))\;/g, "1.0")
svg64 = btoa(svg64.replace(/\\\$(\\\(fill\\\))\;/g, "#45a1ff"))
} else {
// 默认状态 - 根据主题调整
svg64 = svgXml.replace(/\\\$(\\\(fill\\\-opacity\\\))\;/g, "0.5")
// 根据 darkMode 和 themeColorPopupText 设置颜色...
}
return 'data:image/svg+xml;base64,' + svg64
}7. 快捷键支持
支持三种快捷键操作:
javascript
chrome.commands.onCommand.addListener(command => {
if (command === "hotkey-toggle-translation") {
// 切换翻译状态
chrome.tabs.sendMessage(tabs[0].id, { action: "toggle-translation" })
} else if (command === "hotkey-toggle-dual") {
// 切换双语显示模式
twpConfig.set("isShowDualLanguage", ...)
} else if (command === "hotkey-swap-page-translation-service") {
// 切换翻译服务(Google/Yandex)
twpConfig.set("pageTranslatorService", ...)
}
})8. 自动翻译功能
通过 webNavigation API 实现链接点击后的自动翻译:
javascript
function enableTranslationOnClickingALink() {
chrome.tabs.onActivated.addListener(tabsOnActivated)
chrome.tabs.onRemoved.addListener(tabsOnRemoved)
chrome.runtime.onMessage.addListener(runtimeOnMessage)
chrome.webNavigation.onCommitted.addListener(webNavigationOnCommitted)
chrome.webNavigation.onDOMContentLoaded.addListener(webNavigationOnDOMContentLoaded)
}技术特点
- Manifest V3 兼容 - 支持最新的 Chrome 扩展标准
- 跨浏览器支持 - 兼容 Chrome、Firefox、Edge 等主流浏览器
- 移动设备适配 - 针对移动端浏览器做了特殊处理
- 主题感知 - 自动适配浏览器的深色/浅色主题
- 国际化支持 - 使用
chrome.i18nAPI 实现多语言
项目链接
- GitHub 仓库(已归档): https://github.com/immersive-translate/old-immersive-translate
- 新版官网: https://immersivetranslate.com/
- 原始 Fork 来源: https://github.com/FilipePS/Traduzir-paginas-web
许可证
MPL-2.0 (Mozilla Public License 2.0)
分享: