V2EX 20小时前
Chrome 内置 Translator API:本地化翻译新篇章
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入解析了 Chrome 131 Canary 版本推出的 Translator API。该 API 允许开发者在浏览器端实现离线、高效且注重隐私的本地化翻译。文章详细介绍了 API 的优势,包括完全离线支持、数据不出浏览器、实时动态翻译以及极快的响应速度,并与传统的云端翻译服务和静态国际化文件进行了对比。同时,文章提供了 API 的核心方法详解,包括检测可用性、创建翻译器实例和执行翻译,并给出了实战 Demo 的实现步骤,涵盖文本翻译、语言交换、清空文本以及高级的整页自动国际化功能。最后,文章总结了 API 的核心要点、当前限制和未来展望,为开发者提供了在个人博客、内部工具、Chrome 扩展和离线应用等场景下的应用指导。

🌟 **本地化翻译新选择**:Chrome 的 Translator API 允许开发者在浏览器端实现高质量的本地翻译,摆脱了对网络连接的依赖,显著提升了翻译的隐私性和安全性。与传统的云端翻译服务相比,它消除了数据传输至第三方服务器的风险,并避免了 API 调用成本和网络延迟的影响,为用户带来了更流畅、更私密的翻译体验。

🚀 **离线且高效的翻译能力**:该 API 最大的亮点在于其完全离线的工作模式。这意味着用户无需联网即可进行翻译,极大地扩展了翻译功能的使用场景,尤其适用于网络不稳定的环境或对数据隐私有极高要求的用户。本地计算能力确保了翻译过程的快速响应,远超受网络影响的云端服务。

📝 **动态翻译与国际化革新**:Translator API 支持对任意文本进行实时动态翻译,无需像传统 i18n 文件那样手动维护多语言配置。这使得网页能够轻松实现整页的自动国际化,动态更新内容,甚至支持用户生成内容的翻译,极大地降低了多语言支持的开发和维护成本。

🛠️ **实战指南与应用前景**:文章提供了详细的 Demo 实现步骤,包括功能检测、文本翻译、语言交换以及整页自动国际化。虽然目前该 API 仍处于实验阶段,但其在个人博客、内部工具、Chrome 扩展及 PWA 应用等场景下展现出巨大的应用潜力,预示着浏览器端 AI 能力的未来发展方向。

🌐 浏览器内置翻译 API 完全指南

探索 Chrome 最新的 Translator API ,实现离线、高效、隐私友好的本地翻译功能

💡 本文基于 Chrome 131 Canary 版本编写,API 可能会随版本更新而变化。


第一次使用可能需要下载模型 🚀点击查看在线演示 →

一、前言:为什么需要浏览器内置翻译?

1. 传统翻译方案的痛点

在 Web 开发中,我们通常使用以下翻译方案:

2. Translator API 的优势

Chrome 推出的 Translator API 是浏览器内置的本地翻译解决方案,带来了革命性的改变:

特性Translator API云端翻译静态 i18n
离线支持✅ 完全离线❌ 需要网络✅ 离线可用
隐私保护✅ 数据不出浏览器❌ 数据传输到服务器✅ 无数据传输
动态翻译✅ 实时翻译任意文本✅ 实时翻译❌ 仅预定义文本
响应速度⚡ 极快(本地计算)🐌 受网络影响⚡ 极快
成本💰 免费💸 API 调用收费💰 免费
维护成本🔧 低🔧 低🔨 高(多语言文件)

3. 浏览器支持情况

目前 Translator API 正处于实验性阶段,支持情况如下:

💡 提示:虽然目前是实验性功能,但 Chrome 团队正在积极推进标准化,预计未来将成为 Web 标准的一部分。


二、Translator API 官方文档解读

1. API 基本介绍

Translator API 是基于浏览器内置的神经网络翻译模型,能够在本地完成高质量的文本翻译。它是 Chrome AI 计划的一部分,与 Prompt API 、Summarizer API 等共同构成浏览器端 AI 能力。

2. 核心方法详解

2.1 检测 API 可用性

// 检查浏览器是否支持 Translator APIif (!('Translator' in self)) {  console.error('当前浏览器不支持 Translator API');}// 检查特定语言对的可用性const availability = await self.Translator.availability({  sourceLanguage: 'en',  targetLanguage: 'zh'});console.log(availability);// 可能的返回值:// - "unavailable"  : 用户的设备或所请求的会话选项不受支持。设备可能电量不足或磁盘空间不足// - "downloadable" : 需要进行额外的下载才能创建会话。可能需要用户激活才能调用 create()// - "downloading"  : 下载正在进行中,必须先完成下载,然后才能使用会话// - "available"    : 您可以立即创建会话

返回值说明

参考官方文档 - Model Download

2.2 创建翻译器实例

const translator = await self.Translator.create({  sourceLanguage: 'en',  // 源语言( ISO 639-1 代码)  targetLanguage: 'zh'   // 目标语言( ISO 639-1 代码)});

参数说明

2.3 执行翻译

const result = await translator.translate('Hello, world!');console.log(result); // "你好,世界!"

3. 语言支持列表

使用 BCP 47 语言短代码作为字符串。例如,'es' 表示西班牙语,'fr' 表示法语。

目前支持的主流语言(不完全列表):

语言ISO 代码语言ISO 代码
中文(简体)zhzh-CN英语en
日语ja韩语ko
法语fr德语de
西班牙语es俄语ru
意大利语it葡萄牙语pt
阿拉伯语ar印地语hi

注意:具体支持的语言对可能因 Chrome 版本而异,建议使用前通过 availability() 检测。

4. 与传统翻译方案对比

场景一:翻译用户输入内容

传统方案(云端 API )

// 需要调用外部 APIconst response = await fetch('https://api.translate.com/v1/translate', {  method: 'POST',  body: JSON.stringify({ text, from: 'en', to: 'zh' })});const result = await response.json();

❌ 问题:

本地 AI 方案

const translator = await self.Translator.create({  sourceLanguage: 'en',  targetLanguage: 'zh'});const result = await translator.translate(text);

✅ 优势:

场景二:整页国际化

传统方案( i18n 文件)

// en.json{ "welcome": "Welcome", "description": "A translation demo" }// zh.json{ "welcome": "欢迎", "description": "翻译演示" }// 使用document.getElementById('title').textContent = i18n.t('welcome');

❌ 问题:

本地 AI 方案(动态翻译)

// 直接翻译页面上的所有文本async function translatePage(targetLang) {  const translator = await self.Translator.create({    sourceLanguage: 'zh',    targetLanguage: targetLang  });    const elements = document.querySelectorAll('[data-i18n]');  for (const el of elements) {    el.textContent = await translator.translate(el.textContent);  }}

✅ 优势:


三、实战:Demo 实现步骤详解

基于我开发的 Demo (translator-demo.html),我将详细介绍如何从零构建一个完整的翻译应用。

环境准备

浏览器版本要求

    下载 Chrome Canary 或 Dev 版本

    启用实验性功能

打开以下两个 Chrome flags:

chrome://flags/#translation-apichrome://flags/#optimization-guide-on-device-model

设置为 Enabled,然后重启浏览器。

    首次使用注意事项
      首次调用会自动下载语言模型(约 50-200MB )下载时间取决于网络速度(通常 2-5 分钟)模型下载后会缓存,后续使用无需重新下载

功能检测代码

在应用启动时,首先检测 API 是否可用:

async function checkAPIAvailability() {  try {    // 1. 检查浏览器是否支持 Translator API    if (!('Translator' in self)) {      apiStatus.className = "status-banner error";      apiStatus.innerHTML = `        <span>❌</span>        <span>您的浏览器不支持 Translator API 。请使用 Chrome 131+ 并启用相关实验性功能。</span>      `;      translateBtn.disabled = true;      return;    }    // 2. 检查特定语言对是否可用 - 使用 availability() 方法    const translatorCapabilities = await self.Translator.availability({      sourceLanguage: 'zh',      targetLanguage: 'en',    });        if (translatorCapabilities === "unavailable") {      apiStatus.className = "status-banner error";      apiStatus.innerHTML = `        <span>❌</span>        <span>Translator API 不可用</span>      `;      translateBtn.disabled = true;    } else {      apiStatus.className = "status-banner success";      apiStatus.innerHTML = `        <span>✅</span>        <span>Translator API 可用!可以开始使用翻译功能。</span>      `;      translateBtn.disabled = false;      if (translatorCapabilities === "downloadable" || translatorCapabilities === "downloading") {        apiStatus.innerHTML += `<div style="margin-top: 8px; font-size: 0.9em;">📦 正在下载翻译模型...</div>`;      }    }  } catch (error) {    apiStatus.className = "status-banner error";    apiStatus.innerHTML = `      <span>❌</span>      <span>Translator API 不可用: ${error.message}</span>    `;    translateBtn.disabled = true;  }}

核心功能实现

功能一:文本翻译

这是最基础的功能,用户输入文本后点击按钮进行翻译。

步骤 1:HTML 结构
<div class="translate-panel">  <!-- 源语言选择 -->  <select id="sourceLang">    <option value="zh">🇨🇳 中文</option>    <option value="en">🇺🇸 英语</option>    <option value="ja">🇯🇵 日语</option>  </select>  <!-- 输入框 -->  <textarea id="inputText" placeholder="请输入要翻译的文本..."></textarea>  <!-- 目标语言选择 -->  <select id="targetLang">    <option value="en">🇺🇸 英语</option>    <option value="zh">🇨🇳 中文</option>    <option value="ja">🇯🇵 日语</option>  </select>  <!-- 输出框 -->  <textarea id="outputText" disabled placeholder="翻译结果..."></textarea>  <!-- 翻译按钮 -->  <button id="translateBtn" onclick="translateText()">🚀 开始翻译</button></div>
步骤 2:JavaScript 实现
async function translateText() {  const text = document.getElementById('inputText').value.trim();  const source = document.getElementById('sourceLang').value;  const target = document.getElementById('targetLang').value;  const outputText = document.getElementById('outputText');  const translateBtn = document.getElementById('translateBtn');  // 输入验证  if (!text) {    alert('请输入要翻译的文本');    return;  }  if (source === target) {    alert('源语言和目标语言相同,无需翻译');    return;  }  try {    // 禁用按钮,防止重复点击    translateBtn.disabled = true;    translateBtn.textContent = '⏳ 翻译中...';    outputText.value = '';    // 创建翻译器    const translator = await self.Translator.create({      sourceLanguage: source,      targetLanguage: target    });    // 执行翻译    const result = await translator.translate(text);    // 显示结果    outputText.value = result;    // 可选:销毁翻译器释放资源    // translator.destroy();  } catch (error) {    console.error('翻译失败:', error);    alert(`翻译失败: ${error.message}`);    outputText.value = '';  } finally {    // 恢复按钮状态    translateBtn.disabled = false;    translateBtn.textContent = '🚀 开始翻译';  }}
关键要点
    异步处理:所有 API 调用都是异步的,必须使用 async/await错误处理:使用 try-catch 捕获翻译失败的情况用户体验
      翻译时禁用按钮,防止重复点击显示"翻译中"状态使用 finally 确保按钮状态恢复

功能二:交换语言

允许用户一键交换源语言和目标语言,并同时交换输入输出文本。

function swapLanguages() {  const sourceLang = document.getElementById('sourceLang');  const targetLang = document.getElementById('targetLang');  const inputText = document.getElementById('inputText');  const outputText = document.getElementById('outputText');  // 交换语言选择  const tempLang = sourceLang.value;  sourceLang.value = targetLang.value;  targetLang.value = tempLang;  // 交换文本内容  const tempText = inputText.value;  inputText.value = outputText.value;  outputText.value = '';  // 清空输出,等待新的翻译}

功能三:清空文本

function clearText() {  document.getElementById('inputText').value = '';  document.getElementById('outputText').value = '';}

高级功能实现

功能一:整页翻译(自动国际化)

这是 Demo 的核心亮点之一 - 使用 Translator API 实现整个页面的自动翻译。

实现思路
    为需要翻译的元素添加 data-i18n 属性存储原始中文文本点击语言切换按钮时,调用 API 翻译所有文本动态更新页面内容
HTML 标记
<h1 data-i18n="true">🌐 Chrome 内置 AI 翻译器</h1><p data-i18n="true">使用浏览器内置的 Translator API 进行实时翻译</p><button data-i18n="true">🚀 开始翻译</button><textarea placeholder="请输入文本..." data-i18n="true"></textarea>

重要说明

JavaScript 实现
// 当前页面语言let currentLang = "zh";// 存储元素的原始文本(用于恢复)const originalTexts = new Map();// 翻译器缓存(避免重复创建)const pageTranslators = {};/** * 切换页面语言 * @param {string} targetLang - 目标语言代码 */async function switchLanguage(targetLang) {  // 更新按钮状态 - 添加加载动画  const targetBtn = document.querySelector(`.lang-btn[data-lang="${targetLang}"]`);  document.querySelectorAll(".lang-btn").forEach((btn) => {    btn.classList.remove("active", "translating");  });    targetBtn.classList.add("active", "translating");  try {    // 翻译页面内容    await translatePage(currentLang, targetLang);    // 更新当前语言    currentLang = targetLang;  } catch (error) {    console.error('切换语言失败:', error);    alert(`切换语言失败: ${error.message}`);  } finally {    // 移除加载动画    targetBtn.classList.remove("translating");  }}/** * 翻译页面中所有标记为 data-i18n="true" 的元素 * @param {string} sourceLang - 源语言 * @param {string} targetLang - 目标语言 */async function translatePage(sourceLang, targetLang) {  // 如果源语言和目标语言相同,无需翻译  if (sourceLang === targetLang) {    return;  }  try {    console.log(`🌐 开始翻译页面: ${sourceLang} → ${targetLang}`);    // 获取或创建翻译器    const translatorKey = `${sourceLang}-${targetLang}`;    if (!pageTranslators[translatorKey]) {      console.log(`🔧 创建翻译器: ${sourceLang} → ${targetLang}`);      pageTranslators[translatorKey] = await self.Translator.create({        sourceLanguage: sourceLang,        targetLanguage: targetLang      });    }    const translator = pageTranslators[translatorKey];    // 收集所有需要翻译的元素    const elements = document.querySelectorAll('[data-i18n="true"]');        if (elements.length === 0) {      console.log('⚠️ 没有找到需要翻译的元素 (data-i18n="true")');      return;    }    console.log(`📝 找到 ${elements.length} 个需要翻译的元素`);    // 遍历每个元素进行翻译    for (const el of elements) {      // 跳过特定元素(如翻译功能区的输入框)      if (el.id === 'inputText' || el.id === 'outputText') {        continue;      }      // 添加翻译中样式      el.classList.add('translating-text');      try {        // 保存原始文本(首次翻译时)        if (!originalTexts.has(el)) {          if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {            originalTexts.set(el, {              placeholder: el.placeholder,              value: el.value            });          } else {            // 提取纯文本内容(排除子元素)            const textContent = getTextContent(el);            originalTexts.set(el, {              textContent: textContent            });          }        }        // 获取当前文本内容        let textToTranslate = '';        if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {          textToTranslate = el.placeholder;        } else {          textToTranslate = getTextContent(el);        }        // 执行翻译        if (textToTranslate) {          const translated = await translator.translate(textToTranslate);                    // 更新元素内容          if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {            el.placeholder = translated;          } else {            // 只替换文本节点,保留子元素            replaceTextContent(el, translated);          }        }      } catch (error) {        console.error(`翻译元素失败:`, el, error);      } finally {        // 移除翻译中样式        el.classList.remove('translating-text');      }    }    console.log(`✅ 页面翻译完成!`);  } catch (error) {    console.error('❌ 页面翻译失败:', error);    // 移除所有 loading 类    document.querySelectorAll('.translating-text').forEach(el => {      el.classList.remove('translating-text');    });    throw error;  }}/** * 提取元素的纯文本内容(只包含直接文本节点,不包含子元素) */function getTextContent(el) {  let text = '';  for (const node of el.childNodes) {    if (node.nodeType === Node.TEXT_NODE) {      text += node.textContent;    }  }  return text.trim();}/** * 替换元素的文本节点内容,保留子元素 */function replaceTextContent(el, newText) {  // 如果元素没有子元素,直接替换 textContent  if (el.children.length === 0) {    el.textContent = newText;    return;  }  // 如果有子元素(如链接),只替换文本节点  for (const node of el.childNodes) {    if (node.nodeType === Node.TEXT_NODE) {      node.textContent = newText;      break; // 只替换第一个文本节点    }  }}

四、总结

📌 核心要点回顾

    Translator API 的优势

      ✅ 完全离线,保护用户隐私✅ 本地计算,响应速度快✅ 免费使用,无调用限制✅ 动态翻译,无需维护多语言文件

    实现整页翻译的关键步骤

      使用 data-i18n="true" 标记可翻译元素缓存翻译器实例,避免重复创建保存原始文本,支持语言切换正确处理不同类型元素( input 、textarea 、普通元素)保留 HTML 结构,只翻译文本节点

    API 核心方法

    // 检查可用性const availability = await self.Translator.availability({ sourceLanguage, targetLanguage });// 创建翻译器const translator = await self.Translator.create({ sourceLanguage, targetLanguage });// 执行翻译const result = await translator.translate(text);

    当前限制

      仅 Chrome 131+ 支持(实验性功能)需要手动启用两个 Chrome flags首次使用需要下载语言模型不支持批量翻译 API

🚀 应用场景

🔮 未来展望

Chrome 团队正在积极推进浏览器内置 AI 能力的标准化,未来可能会:


🙏 致谢

感谢 Chrome 团队为 Web 开发者带来了如此强大的本地 AI 能力!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Chrome Translator API 浏览器内置翻译 本地化翻译 离线翻译 隐私保护 AI Web 开发 国际化 Chrome Canary Chrome Extension PWA Browser AI Machine Translation Offline Translation Privacy Web Development Internationalization
相关文章