Node.js调用Twilio API报错JSON unexpected token at position 0
问题背景
Express服务新增Twilio视频服务token下发接口,前端调用该接口时抛出JSON unexpected token at position 0错误,暂无法确定是否为Twilio服务侧问题。
后端接口实现代码
const config = require("./config"); const express = require("express"); const bodyParser = require("body-parser"); const pino = require("express-pino-logger")(); const { videoToken } = require("./tokens"); const app = express(); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(pino); const sendTokenResponse = (token, res) => { res.set("Content-Type", "application/json"); res.send( JSON.stringify({ token: token.toJwt(), }) ); }; app.post("/video/token", (req, res) => { const identity = req.body.identity; const room = req.body.room; const token = videoToken(identity, room, config); sendTokenResponse(token, res); });
前端请求逻辑代码
const handleSubmit = useCallback(async () => { setConnecting(true); const data = await fetch("/video/token", { method: "POST", body: JSON.stringify({ identity: username, room: roomName, }), headers: { Accept: "application/json", "Content-Type": "application/json", }, }).then((res) => res.json()); Video.connect(data.token, { name: roomName, }) .then((room) => { setConnecting(false); setRoom(room); }) .catch((err) => { console.error(err); setConnecting(false); }); }, [roomName, username]);
故障排查结论
该错误和Twilio服务侧无关,属于接口请求响应链路问题,按以下优先级排查即可:
- 打开浏览器开发者工具Network面板,找到
/video/token请求查看响应状态码:如果返回4xx/5xx,响应内容基本是HTML格式的错误页(比如服务默认404页、运行时错误堆栈页),不是合法JSON,调用res.json()解析时第一个字符通常是<,直接触发position 0的解析错误。 - 检查pino日志中间件注册顺序:当前代码把
app.use(pino)放在bodyParser注册之后,部分版本的express-pino-logger会在请求异常时往响应流写入非JSON的日志内容,导致响应体开头不符合JSON格式,临时注释pino相关代码即可验证。 - 检查接口是否存在未捕获异常:如果
videoToken方法执行报错(比如Twilio配置项缺失、传入的identity/room参数不符合要求导致token生成失败),且接口没有编写错误捕获逻辑,会直接返回Express默认的HTML格式错误信息,无法被解析为JSON。 - 检查请求路径是否匹配:如果Express服务没有部署在站点根目录,或者本地开发环境没有配置接口代理,
/video/token请求会打到静态资源服务上,返回HTML格式的404页面或者前端入口index.html文件,同样会触发解析错误。
快速定位方法
把前端请求里的JSON解析逻辑临时替换为以下代码,打印原始响应内容就能直接看到非法内容是什么,精准定位问题:
.then(async (res) => { const rawResp = await res.text(); console.log("接口原始返回内容:", rawResp); return JSON.parse(rawResp); })
最高发的触发场景:本地开发时未启动Express后端服务,前端dev server未配置接口代理,请求直接返回了前端项目的index.html文件,第一行的
<!doctype html>被当作JSON解析就会抛出该错误。
内容的提问来源于stack exchange,提问作者Hussain usmani
相关产品推荐
相关产品推荐

