百度翻译 API 是目前少有的可以免费调用的翻译 API,每月可以免费翻译 5万字符,实名认证后可以翻译 100万字符。如果你需要在应用里集成翻译功能,在翻译量不大的情况下,也可以使用免费的百度翻译。

我之前在一个 Electron 软件中也使用过百度翻译 API,Electron 的后端使用的也是 Node.js,这里简单写一下 Node.js 调用百度翻译 API 的方式。

百度翻译 API 的注册可以参考我之前写过的 PotPlayer 使用百度翻译实时翻译外文字幕 。

使用说明

百度翻译 API 可以通过 HTTP 请求来调用,只需要传入翻译内容、语言、API Key、签名 就能翻译,翻译完成后会返回 JSON 格式的翻译结果。

这里稍微麻烦一点的就是签名,下面是签名说明:

  1. 把 App ID、翻译内容、随机数、API Key 拼接在一起
  2. 对拼接后的字符串进行 md5 加密

App ID 和 API KEY 在开通翻译 API 后可以在控制台查看,随机数就是随机生成一个数字,在签名和发送 HTTP 查询的时候都需要用到。

下面是使用 Node.js 生成签名的代码:

const crypto = require('crypto');  // 用来生成 md5 的模块

const appid = 'www.misterma.com';  // 百度翻译的 AppID
const apiKey = 'www.misterma.com';  // 百度翻译的 API Key
const q = 'Are you OK';  // 要翻译的内容

// 生成一个随机数
const salt = Math.floor(Math.random() * 1000);

// 生成签名
let sign = appid + q + salt + apiKey
sign = crypto.createHash('md5').update(sign).digest('hex');

发送 HTTP 请求支持 GET 和 POST,GET 在翻译长文本的时候可能会出错,建议使用 POST。

下面是 HTTP 查询参数说明:

  • q: 要翻译的文本内容
  • from: 原文语言,设置为 auto 可以自动检测
  • to: 译文语言
  • appid: App ID
  • salt: 随机数,需要和签名用到的随机数一样
  • sign: 签名

from 和 to 的语言需要使用百度的语言代码,完整的语言代码表格可以访问 https://fanyi-api.baidu.com/doc/21 ,HTTP 的请求地址是 https://fanyi-api.baidu.com/api/trans/vip/translate 。

翻译完成后会返回 JSON 格式的翻译结果,如下:

{
  "from": "en",
  "to": "zh",
  "trans_result": [
    {
      "src": "Are you ok",
      "dst": "你还好吗?"
    }
  ]
}

如果翻译出错也会返回 JSON:

{
  "error_code": "58000",
  "error_msg": "INVALID_CLIENT_IP",
  "data": {
    "client_ip": "127.0.0.1"
  }
}

通过 error_msg 可以查看错误信息,通过 error_code 在百度的开发文档中也能查到错误信息。

完整代码

下面是完整的 Node.js 翻译代码,包含签名和发送请求,我这里的发送 HTTP 请求会用到 Node.js 自带的 https 模块,关于 https 模块的使用可以看我之前写过的 Node.js 使用 HTTP 和 HTTPS 模块发送 GET 和 POST 请求 ,如果嫌麻烦的话也可以用 axios,关于 axios 的使用可以看 JavaScript 使用 Axios 发送 GET 和 POST 请求 。

完整代码:

const https = require('https');  // 用来发送 HTTP 请求的模块
const crypto = require('crypto');  // 用来生成 md5 的模块
const querystring = require('querystring');  // 用来把对象转换为查询字符串的模块

const appid = 'www.misterma.com';  // 百度翻译的 AppID
const apiKey = 'www.misterma.com';  // 百度翻译的 API Key

const q = 'Are you OK';  // 要翻译的内容
const from = 'auto'  // 原文语言,auto 是自动检测
const to = 'zh';  // 译文语言,这里的 zh 是简体中文

// 生成一个随机数
const salt = Math.floor(Math.random() * 1000);

// 生成签名
let sign = appid + q + salt + apiKey
sign = crypto.createHash('md5').update(sign).digest('hex');

// 要发送的数据
let submitData = {q, from, to, appid, salt, sign};
// 把对象转换为 URL 查询字符串
submitData = querystring.stringify(submitData);

// 配置 https 请求
const req = https.request({
  hostname: 'api.fanyi.baidu.com',
  path: '/api/trans/vip/translate',
  port: 443,
  method: 'post',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': submitData.length
  }
}, res => {
  if (res.statusCode !== 200) {
    // 在控制台输出 http 状态码
    console.log(res.statusCode);
    return false;
  }

  res.on('data', data => {
    // 把接收到的数据转换为 JSON
    data = JSON.parse(data.toString());
    // 检查是否出错
    if (data.error_code !== undefined && data.error_msg !== undefined) {
      // 在控制台输出百度服务器返回的错误信息
      console.log(data.error_msg);
      return false;
    }
    // 如果没有错误就在控制台输出翻译结果
    console.log(data.trans_result);
  });
});

// 设置要发送的内容
req.write(submitData);
// 结束
req.end();

使用 https 模块发送请求的请求地址域名和路径需要分开写,域名写在 hostname ,路径写在 path ,端口如果没有特别说明就是 443。

https 模块接收到的数据是 Buffer 数据,需要调用 toString 方法转换为字符串,然后使用 JSON.parse 转换为对象。