使用JSON.parse解析MVC控制器返回字符串时遇Unexpected token错误
这个问题我之前碰到过,其实核心原因是你混淆了JS字符串的包裹符和JSON本身的格式,咱们一步步拆解:
为什么Chrome控制台正常,但代码里报错?
在Chrome控制台里,你输入的JSON.parse('[{ "When": "", "Value": "NRMFS0131", "Text": "Achieve Montana" }]'),这里的单引号是JavaScript用来包裹JSON字符串的边界符,控制台会自动把单引号去掉,只把里面的[{...}]传给JSON.parse,所以能正常解析。
但如果你的MVC控制器实际返回的响应内容是带单引号包裹的字符串(也就是返回的内容就是'[{...}]',包含首尾的单引号),那JSON.parse会把这两个单引号当成JSON内容的一部分——而JSON规范里只允许用双引号包裹字符串,且整个JSON结构不能被单引号包裹,所以就会抛出Unexpected token ' in JSON at position 0的错误。
解决办法
1. 从源头修正控制器的返回逻辑(推荐)
不要手动给JSON字符串加单引号包裹,直接让MVC框架自动序列化对象:
// 假设你有一个List或数组对象,比如: var data = new List<YourModel> { new YourModel { When = "", Value = "NRMFS0131", Text = "Achieve Montana" } }; // 直接返回JsonResult,框架会输出纯JSON格式 return Json(data);
这样返回的响应内容就是纯JSON数组[{ "When": "", "Value": "NRMFS0131", "Text": "Achieve Montana" }],没有多余的单引号,JSON.parse可以直接解析。
2. 临时修复:如果已经拿到带单引号的字符串
如果暂时没法修改控制器,可以在前端解析前先去掉首尾的单引号:
// 假设responseText是你从控制器拿到的带单引号的字符串 const cleanStr = responseText.replace(/^'|'$/g, ''); const parsedData = JSON.parse(cleanStr);
这个正则会匹配字符串开头和结尾的单引号并替换为空,得到合法的JSON字符串后再解析。
3. 验证实际返回内容
打开浏览器开发者工具(F12),切换到Network面板,找到这个请求,查看Response标签页的内容,确认是不是真的包含首尾的单引号——这是排查问题最直接的方式。
内容的提问来源于stack exchange,提问作者mayur manudhanya

