解决Chrome报错js:Uncaught TypeError- Cannot use 'in' operator to search for 'length' in [{"id":"636","...
一、问题描述
在使用ajax的 $.get 和 $.post 方法获取后台返回的json数据,使用 jquery的 $.each方法遍历的时候,浏览器报错:
Uncaught TypeError: Cannot use 'in' operator to search for 'length' in [{"id":"636","isNewRecord":false,"name":"长春市","sort":30,"code":"220100","type":"3","parentId":"0"},{"id":"648","isNewRecord":false,"name":"吉林市","sort":30,"code":"220200","type":"3","parentId":"0"},{"id":"659","isNewRecord":false,"name":"四平市","sort":30,"code":"2 。。。

二、相关代码参考
1、前台代码
$("#city").change(function(){
var cityId=$("#city").val();
var cityName=$("#city").find("option:selected").text();
$.get($("#spanid").text()+"/rankController/cityJson",{"id":cityId},function(data){
// 清空 城市下面的区县
$("#county").empty();
$("#county").append("<option value=''>"+'--请选择--'+"</option>");
// each 遍历json数据
$.each(data,function(k,v){
var _ele="<option value='"+v.id+"'>"+v.name+"</option>";
$("#county").append(_ele);
});
});
});
2、后台代码
@RequestMapping(value="/cityJson")
@ResponseBody
public List<Area> cityJson(String id){
List<Area> provinceList = areaService.getAreaListByParentId(id);
return provinceList;
}
三、问题分析
1、根据错误代码定位进jQuery源码,$.each 方法遍历的是json对象,而非json字符串。当传入json字符串进行遍历的时候,就会报错: Cannot use 'in' operator to search for ...
四、问题解决
将 json字符串转换为json对象即可,方法有以下三种。
1、data= eval("("+jsonStr+")"); // 原生js方法
2、data=JSON.parse(jsonStr); // 原生js方法
3、data= $.parseJSON(jsonStr); // 需要jquery
五、问题延伸(一)
1、该项目是个ssm结构,看 二-2 后台代码,可以看到后台返回的是json对象,怎么到前台就变成了json字符串呢?
思考:是否和 $.get 方法有关系呢? 换用 $.post 和 $.ajax 方法,在后台依旧返回json对象的情况下,进行测试。
2、ajax 方法测试
$.ajax({
url : $("#spanid").text() + "/rankController/cityJson",
type : 'post',
data : { "id" : cityId },
dataType : 'json',
success : function(data) {
console.info('----》', typeof data); // object
$.each(data, function(k, v) {
var _ele = "<option value='" + v.id + "'>" + v.name + "</option>";
$("#county").append(_ele);
});
}
});
3、post 方法测试
$.post($("#spanid").text()+"/rankController/cityJson",{"id":cityId},function(data){
console.info('----》', typeof data); // string
$.each(data,function(k,v){
var _ele="<option value='"+v.id+"'>"+v.name+"</option>";
$("#county").append(_ele);
});
});
结论: $.get和$.post方法请求,后台返回json对象,前台变成了json字符串;而
$.ajax方法 后台返回json对象,前台获取的也是json对象,无影响。(想去研究下 $.get的源码,找了半天,不好意思,没找到,看不懂。)
那么写到这里,对于错误:Cannot use 'in' operator to search for ... 又增加了一种解决办法,更换从后台获取数据的方法,
由 $.get 或 $.post 更换为 $.ajax 方法即可解决报错问题。
六、问题延伸(二)
1、继续查看 二-2 后台代码,后台的json对象怎么到前台就变成了json字符串呢?
思考: 是否和 SpringMVC 有关系呢?
2、查看 svn 提交记录,找到了一个 springmvc.xml 中配置修改的问题:

然后回滚上一版本,去掉这个配置,$.get和$.post 请求,后台返回 json对象,前台获取的也是json对象,报错问题也已经解决。
3、 引入了一个新的问题, IE 浏览器 请求返回json的url会出现json文件下载的情况重现了。
解决: <value>text/html;charset=UTF-8</value> 修改为:
<value>text/json;charset=UTF-8</value>
结论: 修改springmvc.xml的配置文件为:
<value>text/json;charset=UTF-8</value>
a . 解决了 $.get 后台返回 json对象,前台变成了json字符串而引起报错的问题
b. 解决了 IE 浏览器 请求返回json的url会出现json文件下载的情况
c. 这应该是最完美的解决方案!
七、 未解决的问题
1、 <value>text/html;charset=UTF-8</value> 仅仅是一个编码的设置,为何会影响 $.get 、$.post 方法的返回值类型呢?
2、<value>text/json;charset=UTF-8</value> 和上一个,这两个编码的作用是什么呢?
3、对于$.ajax 方法为何就没有影响呢?
项目版本信息情况: 1. springMVC 4.0+ ; jQuery v.3.2.1
技术路漫漫,总有一天我会揭开迷雾找到原因所在的,若您知道其中原因所在,麻烦留言告知,谢谢。