JSON.parse报错,Unexpected token o in JSON at position 1,Unexpected token in JSON at position 650
2017-04-15 00:22

JSON报错问题的解决

    今天在项目中,有一个angularJS的页面,使用$http请求后台返回JSON,结果报错Unexpected token in JSON at position 650,控制台显示的是angular内部JSON.parse时报错的。这就定位到不是angular的问题,是返回的JSON字符串有问题。然后查看开发者工具中的network,找到返回的结果,拷贝出来,通过FE工具格式化JSON,这个工具没有报错,能够正常转换。

    之后修改代码,在$http添加transformResponse方法,并且把返回的结果绑定到window对象上。

$http({
    url:link,
    data:param,
    transformResponse:function(rst){
        window.rcdt=rst;
    }
}).success(function(res){
    //....
});

对代码做了以上修改后,在chrome的控制台里面通过

输入window.rcdt打印出返回的字符串,看不出问题来,

然后通过,JSON.parse(window.rcdt),报错Unexpected token in JSON at position 650。

之后,再在控制台输入window.rcdt=window.rcdt.replace(/\s+/,""),将字符串中的空格去除。

这时候再输入JSON.parse(window.rcdt);JSON转换正常,没有报错。

到这里,算是定位到问题,是JSON中包含了特殊字符。

之后又找到请求url对应的后台,发现后台返回的是一个jsp页面,并且当初是我为了省事在jsp页面中使用EL表达式拼接的JSON字符串。

[
<c:foreach items="${myList}" var="me" varStatus="st">
   {"name":"${me.name}","age":"${me.age}","content":"${me.content}"}<c:if test="!st.last">,</c:if>
</c:foreach>
]

在JSP页面中是这样写的,通过el表达式和JSTL标签生成的JSON字符串。这种写法本没有错误,能够正确返回JSON字符串的。

但是,问题就出在${me.conent}上,它的值是通过前台输入保存的.

blob.png

前台这样输入后,获取的textarea中的value值里面,包换了换行符“\n”。这个换行符在前台展示是可以的,浏览器不认它是换行,但是保存数据库,并且后台没有对换行符进行处理。所以最后获取到的JSON字符串中也就包含了换行符。而JSON.parse报错的原因就是因为换行符。

所以,要对conent中的换行符进行替换。

<% request.setAttribute("vv","\n");%>
[
<c:foreach items="${myList}" var="me" varStatus="st">
   {"name":"${me.name}","age":"${me.age}","content":"${fn:replace(me.content,vv,'')}"}<c:if test="!st.last">,</c:if>
</c:foreach>
]

使用jstl的fn函数对content中的换行符进行替换。因为replace函数中直接填"\n"会报错,所以使用request.setAttribute将“\n”设置为变量再使用,这样就能正常替换了。

到这里,问题解决了,前台也能正常转换成JSON了,不再报错了。这个问题说起来简单,但找问题的时候,花了两个小时。所以记录下来,也便于遇到同样问题的人能够快速解决问题。

另外,如果JSON.parse报错为:Unexpected token o in JSON at position 1,那就很有可能不是JSON字符串的问题,而是你调用了两次JSON.parse导致的。

或者对已经是JSON对象的对象调用JSON.parse也会报这个错误。


原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(7978)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1