JSON.parse()报错“Unexpected token u”主因是传入null/undefined而非字符串,应先校验typeof res.data==='string' && res.data.trim()!==''再解析;推荐不设dataType:'json',手动控制解析以规避非2xx响应丢失数据等问题。

uni-app里JSON.parse()报错:Unexpected token u in JSON at position 0
这是最常见的 JSON 解析失败,本质不是 JSON 格式问题,而是你传给 JSON.parse() 的根本不是字符串——比如后端返回了 null、undefined 或空响应,JSON.parse(null) 就会抛出这个错误。
- 先检查响应体是否为空:
res.data是null、undefined还是空字符串'',再决定是否调用JSON.parse() - 不要直接写
JSON.parse(res.data),加一层守卫:typeof res.data === 'string' && res.data.trim() !== '' - uni-app 的
uni.request()默认不会自动解析 JSON,res.data是原始响应体(可能为对象、字符串或 ArrayBuffer),取决于后端Content-Type和你是否配置了dataType: 'json'
uni-app中dataType: 'json'到底要不要设
设了它,uni-app 会在底层帮你调一次 JSON.parse();没设,res.data 就是原始字符串(或其它类型),得自己 parse。但这个“自动解析”有陷阱。
- 如果后端返回非标准 JSON(比如带 BOM、尾部逗号、单引号),
dataType: 'json'会直接失败,且错误堆栈不明确,难定位 - 如果后端返回状态码非 2xx(如 401、500),但响应体仍是 JSON(比如
{"code":401,"msg":"未登录"}),设了dataType: 'json'反而会让res.data变成undefined(uni-app 对非 2xx 响应默认不解析) - 推荐统一不设
dataType,手动控制解析时机,更可控
后端返回 HTML 或重定向页面导致JSON.parse()崩溃
这不是数据格式问题,是请求被拦截或跳转了——比如登录态失效,Nginx 或后端直接返回了登录页 HTML,前端却当成 JSON 解析,自然报 Unexpected token 。
- 在解析前快速判断:
res.data.toString().trim().startsWith('{') || res.data.toString().trim().startsWith('[') - 更稳妥的做法:检查
res.header['Content-Type']是否包含application/json,不匹配就别硬 parse - 真遇到 HTML 响应,说明请求链路出了问题(鉴权失败、跨域被拒、代理配置错),优先查网络面板里的 Response Preview,而不是改解析逻辑
uni-app安全处理后端数据:避免eval、with和任意JSON.parse
有些老代码会用 JSON.parse(data, (k, v) => { ... }) 的 reviver 做字段过滤,但 reviver 无法阻止原型污染(如 {"__proto__": {"polluted": true}}),也不防恶意函数字符串。
- 永远不要对不可信数据使用
eval、Function构造器或with -
JSON.parse()本身是安全的,但解析后的对象若直接赋值给 Vue 响应式数据(如this.userInfo = parsed),可能触发意外响应式副作用(尤其含__proto__、constructor等属性时) - 建议用结构化克隆过滤掉危险键:
JSON.parse(JSON.stringify(parsed))(简单场景够用),或用lodash.omit显式白名单字段 - 后端字段命名尽量避开
__开头、constructor、prototype,前端也别用它们做 key
真正容易被忽略的是:uni-app 在 H5 和小程序平台对空响应、重定向、Content-Type 的处理不一致。同一段解析逻辑,在微信小程序里可能静默失败,在 H5 里却报错,所以守卫逻辑不能只写一次,得结合 uni.getSystemInfoSync().platform 做微调。









