使用@iamtraction/google-translate库调用时出现SyntaxError: Unexpected token < in JSON at position 0错误的原因排查
@iamtraction/google-translate库调用时出现SyntaxError: Unexpected token < in JSON at position 0错误的原因排查
嘿,这个错误我之前也碰到过,咱们一步步拆解问题根源和解决思路:
错误核心原因
Unexpected token < in JSON at position 0这个报错的本质很明确:你的代码期望谷歌翻译接口返回JSON格式的响应数据,但实际上收到的是HTML内容(HTML页面的开头通常是<html>或<!DOCTYPE html>,所以第一个字符就是<,直接导致JSON解析失败)。
具体触发场景分析
能正常运行突然报错,大概率是下面几种情况:
- 谷歌反爬机制触发:
@iamtraction/google-translate是基于谷歌翻译网页版接口做的非官方封装,谷歌会检测请求频率、请求头合法性。如果你的请求太频繁,或者请求头模拟得不像正常浏览器,就会被拦截,返回人机验证页面、403错误页这类HTML内容。 - 库依赖或版本问题:报错里提到的
undici是这个翻译库的依赖,可能它和你当前的Node.js版本不兼容;或者翻译库本身没及时适配谷歌接口的更新,导致返回内容结构变了,不再是预期的JSON。 - 网络环境异常:你的服务器IP被谷歌标记为异常、网络代理失效,或者网关返回了错误页面,导致请求没正常到达谷歌翻译接口,拿到的是错误HTML。
可行的解决建议
- 给重试逻辑加限制和延迟:你当前的代码在
catch里无限递归调用run(),这会让请求频率更高,反而加重反爬限制。改成有限重试+延迟:module.exports = function({ string, from, to }) { return new Promise(resolve => { let retryCount = 0; const MAX_RETRY = 3; run(); async function run() { try { const res = await translate(string, { from, to }); return resolve(res.text); } catch(err) { retryCount++; console.log(`重试第${retryCount}次,错误信息:`, err); if(retryCount <= MAX_RETRY) { // 延迟1秒再重试,降低请求频率 setTimeout(() => run(), 1000); } else { resolve("翻译失败:已达到最大重试次数"); } } } }); } - 添加合法的请求头:模拟正常浏览器的
User-Agent,很多非官方库支持自定义请求配置,你可以查看@iamtraction/google-translate的文档,添加类似这样的请求头:const res = await translate(string, { from, to, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } }); - 更新依赖库:执行
npm update @iamtraction/google-translate,看看作者是否已经修复了接口适配的问题。 - 检查网络环境:如果是服务器IP的问题,可以尝试更换IP或使用合规的代理服务,避免被谷歌拦截。
备注:内容来源于stack exchange,提问作者Raol mAX




