AJAX请求触发JSON.parse报错:[object Object]不是有效JSON
JSON.parse报错但JSON校验合法的问题分析
问题背景
一段从2018年起稳定运行的AJAX代码,本周突然抛出JSON解析错误:
出错代码
function fncGetUsuarioProducao(p1) { $.ajax({ type: "POST", url: "cadRecebimentoProducao.aspx/GetUsuarioCartaoAcesso", data: JSON.stringify({ codCartaoAcesso: p1 }), contentType: "application/json; charset=utf-8", dataType: "json", success: function (result) { if (result.length == 4) { $("#divAlerta").css("display", ""); return false; } else { $("#divAlerta").css("display", "none"); var json = JSON.parse(result); opener.document.getElementById("hiddenIdUsuario").value = json.IdUsuario; opener.document.getElementById("txtUsuarioProducao").value = json.Funcionario.ContaUsuarioDominio; window.opener.document.form1.submit(); window.parent.close(); } }, failure: function (response) { alert(response.d); } }); }
报错信息
Uncaught SyntaxError: "[object Object]" is not valid JSON at JSON.parse (<anonymous>) at Object.success (cadRecebimentoProducao.aspx?IdSolicitacaoAnalise=359139&Quantidade=2&Unidade=LI:153:41) at j (jquery.min.js:2:26925) at Object.fireWith [as resolveWith] (jquery.min.js:2:27738) at x (jquery.min.js:4:11253) at XMLHttpRequest.<anonymous> (jquery.min.js:4:14765)
用户排查:在JSON.parse前添加console.log(result),将输出内容复制到JSON校验工具,显示格式完全合法。
核心原因
问题出在dataType: "json"这个配置上:
- jQuery会自动根据
dataType的设置,把服务器返回的JSON字符串解析成JavaScript对象。此时success回调里的result已经是一个对象,而非原始的JSON字符串。 - 当你对一个对象调用
JSON.parse()时,JavaScript会先把对象转为默认字符串"[object Object]",这个字符串显然不是合法JSON,所以触发解析错误。
之前代码能正常运行,是因为服务器原本返回的是嵌套的JSON字符串——比如服务器返回的内容本身是"{\"IdUsuario\":123,\"Funcionario\":{...}}"这种格式的字符串,jQuery解析后得到的还是字符串,此时二次调用JSON.parse()是有效的。但本周服务器端大概率做了调整,直接返回了标准的JSON数据,不再嵌套字符串,导致原有逻辑冲突。
解决方案
直接删除JSON.parse(result)这一步,直接使用result对象即可:
修改后的success回调代码:
success: function (result) { if (result.length == 4) { $("#divAlerta").css("display", ""); return false; } else { $("#divAlerta").css("display", "none"); // 直接使用解析后的result对象,无需二次解析 opener.document.getElementById("hiddenIdUsuario").value = result.IdUsuario; opener.document.getElementById("txtUsuarioProducao").value = result.Funcionario.ContaUsuarioDominio; window.opener.document.form1.submit(); window.parent.close(); } }
额外注意:如果是ASP.NET WebMethod接口,返回的数据通常会包裹在d属性里,所以可能需要改成result.d.IdUsuario,可以通过console.log(result)确认返回结构后调整。
内容的提问来源于stack exchange,提问作者Sergio Gamboa
相关产品推荐
相关产品推荐

