百度翻译 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: 签名

fromto 的语言需要使用百度的语言代码,完整的语言代码表格可以访问 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 转换为对象。