JSON.parse报错“Unexpected end of JSON input”主因是options.data为空、未解码或截断,须用try/catch包裹decodeURIComponent和JSON.parse;组件绑定对象需避免解构等语法,改用JSON.stringify或data选项;uni.request取值应校验状态码并用UTSJSONObject或TS泛型;大JSON需拆分、懒加载及缓存。

JSON.parse 报错:Unexpected end of JSON input 怎么办
这是最常见也最容易被忽略的问题——options 里传来的参数根本不是合法 JSON 字符串,而是空字符串、undefined 或被截断的半截内容。真机跳转时网络抖动、URL 长度限制(微信小程序 URL 最长 2048 字符)、前端未编码就拼接,都会导致这个错误。
必须加 try/catch,且不能只捕获 JSON.parse,要从解码开始包住:
onLoad(options) {
try {
const raw = decodeURIComponent(options.data || '');
if (!raw.trim()) throw new Error('empty data');
const data = JSON.parse(raw);
this.dataObj = data;
} catch (e) {
console.error('JSON parse failed:', e, { options });
this.dataObj = {};
}
}
- 永远不要假设
options.data存在或非空,它可能就是"" -
decodeURIComponent必须在JSON.parse前调用,否则中文、&、等字符会直接破坏 JSON 结构 - 如果参数体积预估 > 2KB,改用
uni.setStorageSync('tempData', obj)+ 路由传 key,绕过 URL 限制
组件里传对象用 :data="{...}" 为什么编译报 Expected ',' or '}' after property value
这不是运行时错误,是 uniapp 编译器在解析组件标签属性时,把 Vue 模板里的 JS 表达式误当成 JSON 字符串去解析了。尤其在 vue3 + uniapp 组合下,编译器会对 :data 的值做静态分析和序列化,一旦遇到解构、函数、动态 key、可选链(?.)等语法,就会在位置 33 左右爆 JSON 解析失败。
根本解法是避免让编译器“猜”你的表达式:
- 写成
:data="JSON.stringify({ name: 'test', id: 123 })",显式转字符串,不给编译器留机会 - 复杂对象别硬塞模板,改用
data选项或setup里定义后绑定::data="myPayload" - 禁止在
:xxx绑定中使用?.、??、import()、function(){}等非纯字面量结构
uni.request 返回的 res.data 怎么安全取值
JS 写法 res.data.list[0].name 在 H5/APP 正常,但在小程序端(尤其是 UniApp X / UTS 环境)会直接报类型错误或 undefined 访问异常——因为 res.data 是 any,而小程序底层对属性访问做了强约束。
推荐两种方式,按项目阶段选:
- 过渡期用
UTSJSONObject:先断言const data = res.data as UTSJSONObject,再用data.getString('list[0].name'),支持深层 keypath,不崩溃但无类型提示 - 长期维护项目务必用
type+ 泛型:粘贴接口返回样例 JSON 到 HBuilderX,右键「转 type」生成 TS 接口,然后uni.request,享受完整类型推导和 IDE 提示({...}) - 无论哪种,都要检查
res.statusCode === 200且res.data非空,服务端字段缺失比前端代码出错更常见
省市区三级数据这类大 JSON 怎么加载不卡顿
几百 KB 的 area-full.json 直接 import 进页面,首次渲染会明显卡顿,尤其低端安卓机。关键不是“能不能解析”,而是“要不要一次性全载”。
真实项目该这么做:
- 拆分数据源:用扁平化数组(id/pid/name)代替嵌套结构,体积小 30%+,查找可用 Map 预建索引
- 懒加载:首页只 import 省份列表;用户点开某省,再
import('./areas/shanghai.json')动态加载该省数据 - 缓存策略:
uni.getStorageSync('area_cache')存一次,后续直接读,避免重复解析 - 别在
onLoad里同步JSON.parse大文件,改用setTimeout(() => {...}, 0)让出主线程
最易被忽略的一点:JSON 文件本身别放 /static 下用 require 加载——uniapp 会把它当资源拷贝,失去 tree-shaking 和按需加载能力;应该放在 /common/data 下,走模块导入流程。











