$.ajax()方法从服务器获取json数据

一.什么是json

json是一种取代xml的数据结构,和xml相比,它更小巧但描述能力却很强,网络传输数据使用流量更少,速度更快。

json就是一串字符串,使用下面的符号标注。

{键值对} : json对象

[{},{},{}] :json数组

"" :双引号内是属性或值

: :冒号前为键,后为值(这个值可以是基本数据类型的值,也可以是数组或对象),所以 {"age": 18} 可以理解为是一个包含age为18的json对象,而[{"age": 18},{"age": 20}]就表示包含两个对象的json数组。也可以使用{"age":[18,20]}来简化上面的json数组,这是一个拥有一个age数组的对象。

二.$.ajax()方法中dataType属性的取值

$.ajax()方法中dataType属性要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText【在第三部分解释】,并作为回调函数参数传递。可用的类型如下:

xml:返回XML文档,可用JQuery处理。

html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。

script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。

json:返回JSON数据。

jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。

三.Mime数据类型及response的setContentType()方法

什么是MIME类型?在把输出结果传送到浏览器上的时候,浏览器必须启动适当的应用程序来处理这个输出文档。这可以通过多种类型MIME(多功能网际邮件扩充协议)来完成。在HTTP中,MIME类型被定义在Content-Type header中。

 如,架设你要传送一个Microsoft Excel文件到客户端。那么这时的MIME类型就是“application/vnd.ms-excel”。在大多数实际情况中,这个文件然后将传送给 Execl来处理(假设我们设定Execl为处理特殊MIME类型的应用程序)。在Java中,设定MIME类型的方法是通过Response对象的ContentType属性。比如常用:response.setContentType("text/html;charset=UTF-8")进行设置。

最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。

每个MIME类型由两部分组成,前面是数据的大类别,例如文本text、图象image等,后面定义具体的种类。

常见的MIME类型:

超文本标记语言文本 .html,.html text/html

普通文本 .txt text/plain

RTF文本 .rtf application/rtf

GIF图形 .gif image/gif

JPEG图形 .ipeg,.jpg image/jpeg

au声音文件 .au audio/basic

MIDI音乐文件 mid,.midi audio/midi,audio/x-midi

RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio

MPEG文件 .mpg,.mpeg video/mpeg

AVI文件 .avi video/x-msvideo

GZIP文件 .gz application/x-gzip

TAR文件 .tar application/x-tar

客户程序从服务器上接收数据的时候,它只是从服务器接受数据流,并不了解文档的名字,因此服务器必须使用附加信息来告诉客户程序数据的MIME类型。

服务器在发送真正的数据之前,就要先发送标志数据的MIME类型的信息,这个信息使用Content-type关键字进行定义,例如对于HTML文档,服务器将首先发送以下两行MIME标识信息,这个标识并不是真正的数据文件的一部分。

Content-type: text/html


注意,第二行为一个空行,这是必须的,使用这个空行的目的是将MIME信息与真正的数据内容分隔开。

如前面所说,在Java中,设定MIME类型的方法是通过Response对象的ContentType属性,设置的方法是使用response.setContentType(MIME)语句,response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。

Tomcat的安装目录\conf\web.xml中就定义了大量MIME类型 ,可以参考。比如可以设置:

response.setContentType("text/html; charset=utf-8"); html

response.setContentType("text/plain; charset=utf-8"); 文本

application/json json数据

这个方法设置发送到客户端的响应的内容类型,此时响应还没有提交。给出的内容类型可以包括字符编码说明,例如:text/html;charset=UTF-8。如果该方法在getWriter()方法被调用之前调用,那么响应的字符编码将仅从给出的内容类型中设置。该方法如果在getWriter()方法被调用之后或者在被提交之后调用,将不会设置响应的字符编码,在使用http协议的情况中,该方法设置 Content-type实体报头。

四.使用$.ajax()方法获取json数据的三种方式

dataType参数的配置决定了jquery如何帮助我们自动解析服务器返回的数据,有几种方式可以获取后台返回的json字符串并解析为json对象,下面是Java为例解释,下面三中方式的结果都是图一所示,项目运行在内网,无法截图,只能拍照,见谅。


1、$.ajax()参数中不设置dataType,后台response也不设置返回类型,则默认会以普通文本处理【response.setContentType("text/html;charset=utf-8");也是作为文本处理】,js中需要手动使用eval()或$.parseJSON()等方法将返回的字符串转换为json对象使用。

[java]  view plain  copy
  1. //Java代码:后台获取单个数控定位器的历史表格的数据  
  2.     public void getHistorySingleData() throws IOException{  
  3.         HttpServletRequest request = ServletActionContext.getRequest();  
  4.         HttpServletResponse response = ServletActionContext.getResponse();  
  5.         response.setHeader("Content-type""text/html;charset=UTF-8");  
  6.         response.setContentType("text/html;charset=utf-8");  
  7.         String deviceName = request.getParameter("deviceName");  
  8.         String startDate= request.getParameter("startDate");  
  9.         String endDate = request.getParameter("endDate");  
  10.         SingleHistoryData[] singleHistoryData = chartService.getHistorySingleData(deviceName,startDate, endDate);  
  11.         System.out.println(singleHistoryData.length);  
  12.         System.out.println(JSONArray.fromObject(singleHistoryData).toString());//打印:[{"time":"2016-11-11 10:00:00","state":"运行","ball":"锁紧",....},{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....},{},{}....]查到几条singleHistoryData对象就打印几个对象的信息{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....}  
  13.         response.getWriter().print(JSONArray.fromObject(singleHistoryData).toString());  
  14.     }  

[javascript]  view plain  copy
  1. /*js代码:选择查询某一时间段的数据,点击查询之后进行显示*/  
  2.    $("#search").click(function () {  
  3.     var data1 = [];  
  4.     var n;  
  5.     var deviceName=$("body").attr("id");   
  6.        var startDate = $("#startDate").val();  
  7.        var endDate = $("#endDate").val();  
  8.        $.ajax({  
  9.           url:"/avvii/chart/getHistorySingleData",  
  10.           type:"post",  
  11.           data:{  
  12.               "deviceName":deviceName,  
  13.               "startDate": startDate,  
  14.               "endDate": endDate  
  15.           },  
  16.           success: function (data) {  
  17.            alert(data);//---->弹出[{"time":"2016-11-11 10:00:00","state":"运行","ball":"锁紧",....},{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....},{},{}....],后台传过来几条singleHistoryData对象就打印几个对象的信息{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....}  
  18.            alert(Object.prototype.toString.call(data));  //--->弹出[object String],说明获取的是String类型的数据  
  19.            var JsonObjs = eval("(" + data + ")");      //或者:var JsonObjs = $.parseJSON(data);  
  20.            alert(JsonObjs);//alert(JsonObjs);---->弹出[object Object],[object Object],[object Object][object Object],[object Object],[object Object]……后台传过来几条singleHistoryData对象就打印几个[object Object]  
  21.               n=JsonObjs.length;  
  22.               if(n==0){  
  23.                alert("您选择的时间段无数据,请重新查询");  
  24.               }  
  25.            for(var i = 0; i < JsonObjs.length; i++){                         
  26.                     var name  = JsonObjs[i]['time'];//针对每一条数据:JsonObjs[i],或者:JsonObjs[i].time  
  27.                     var state = JsonObjs[i]['state'];  
  28.                     var ball  = JsonObjs[i]['ball'];  
  29.                     var xd    = JsonObjs[i]['xd'];  
  30.                     var yd    = JsonObjs[i]['yd'];  
  31.                     var zd    = JsonObjs[i]['zd'];  
  32.                     var xf    = JsonObjs[i]['xf'];  
  33.                     var yf    = JsonObjs[i]['yf'];  
  34.                     var zf    = JsonObjs[i]['zf'];  
  35.                        data1[i] = {name:name,state:state,ball:ball,xd:xd,yd:yd,zd:zd,xf:xf,yf:yf,zf:zf};//个数与下面表头对应起来就可以了,至于叫什么名字并不影响控件的使用  
  36.               }  
  37.            if(JsonObjs.length != 10){  
  38.                for(var j=0;j<(10-((JsonObjs.length)%10));j++){               //补全最后一页的空白行,使表格的长度保持不变  
  39.                    data1[j+JsonObjs.length] = {name:" ",state:"",ball:"",xd:"",yd:"",zd:"",xf:"",yf:"",zf:""};   
  40.                }  
  41.            }  
  42.               var userOptions = {  
  43.                       "id":"kingTable",                                             //必须 表格id  
  44.                       "head":["时间","运行状态","球头状态","X向位置/mm","Y向位置/mm","Z向位置/mm","X向承载力/Kg","Y向承载力/Kg","Z向承载力/Kg"],  //必须 thead表头  
  45.                       "body":data1,                                                 //必须 tbody 后台返回的数据展示  
  46.                       "foot":true,                                                      // true/false  是否显示tfoot --- 默认false  
  47.                       "displayNum": 10,                                                 //必须   默认 10  每页显示行数  
  48.                       "groupDataNum":6,                                                 //可选    默认 10  组数  
  49.                       sort:false,                                                       // 点击表头是否排序 true/false  --- 默认false  
  50.                       search:false,                                                     // 默认为false 没有搜索  
  51.                       lang:{  
  52.                           gopageButtonSearchText:"搜索"  
  53.                       }  
  54.               }  
  55.               var cs = new KingTable(null,userOptions);  
  56.           }  
  57.       });   
  58.   });  

2、$.ajax()参数中设置dataType="json",则jquery会自动将返回的字符串转化为json对象。后台可以设置为:推荐response.setContentType("text/html;charset=utf-8");或者response.setContentType("application/json;charset=utf-8");

[java]  view plain  copy
  1. //Java代码:后台获取单个数控定位器的历史表格的数据  
  2. public void getHistorySingleData() throws IOException{  
  3.     HttpServletRequest request = ServletActionContext.getRequest();  
  4.     HttpServletResponse response = ServletActionContext.getResponse();  
  5.     response.setHeader("Content-type""text/html;charset=UTF-8");  
  6.     response.setContentType("text/html;charset=utf-8");  
  7.     String deviceName = request.getParameter("deviceName");  
  8.     String startDate= request.getParameter("startDate");  
  9.     String endDate = request.getParameter("endDate");  
  10.     SingleHistoryData[] singleHistoryData = chartService.getHistorySingleData(deviceName,startDate, endDate);  
  11.     System.out.println(singleHistoryData.length);  
  12.     System.out.println(JSONArray.fromObject(singleHistoryData).toString());//打印:[{"time":"2016-11-11 10:00:00","state":"运行","ball":"锁紧",....},{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....},{},{}....]查到几条singleHistoryData对象就打印几个对象的信息{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....}  
  13.     response.getWriter().print(JSONArray.fromObject(singleHistoryData).toString());  
  14. }  
[javascript]  view plain  copy
  1. /*js代码:页面首次加载时,显示规定时间段的数据*/   
  2.     var data1 = [];  
  3.     var deviceName=$("body").attr("id");   
  4.     var startDate = $("#startDate").val("2000-01-01 00:00:00");  
  5.     var endDate = $("#endDate").val("2018-01-01 00:00:00");  
  6.     $.ajax({  
  7.        url:"/avvii/chart/getHistorySingleData",  
  8.        type:"post",  
  9.        data:{  
  10.            "deviceName":deviceName,  
  11.            "startDate""2000-01-01 00:00:00",  
  12.            "endDate""2018-01-01 00:00:00"  
  13.        },  
  14.        dataType:"json",  
  15.        success: function (data) {  
  16.            alert(data);//---->弹出[object Object],[object Object],[object Object][object Object],[object Object],[object Object]……后台传过来几条singleHistoryData对象就打印几个json对象:[object Object]  
  17.            for(var i = 0; i < data.length; i++){                         
  18.                     var name  = data[i]['time'];  
  19.                     var state = data[i]['state'];  
  20.                     var ball  = data[i]['ball'];  
  21.                     var xd    = data[i]['xd'];  
  22.                     var yd    = data[i]['yd'];  
  23.                     var zd    = data[i]['zd'];  
  24.                     var xf    = data[i]['xf'];  
  25.                     var yf    = data[i]['yf'];  
  26.                     var zf    = data[i]['zf'];  
  27.                     data1[i] = {name:name,state:state,ball:ball,xd:xd,yd:yd,zd:zd,xf:xf,yf:yf,zf:zf};  
  28.            }  
  29.            if(data.length != 10){  
  30.                for(var j=0;j<(10-((data.length)%10));j++){               //补全最后一页的空白行,使表格的长度保持不变  
  31.                    data1[j+data.length] = {name:" ",state:"",ball:"",xd:"",yd:"",zd:"",xf:"",yf:"",zf:""};   
  32.                }  
  33.            }  
  34.            var userOptions = {  
  35.                    "id":"kingTable",                                                //必须 表格id  
  36.                    "head":["时间","运行状态","球头状态","X向位置/mm","Y向位置/mm","Z向位置/mm","X向承载力/Kg","Y向承载力/Kg","Z向承载力/Kg"],  //必须 thead表头  
  37.                    "body":data1,                                                    //必须 tbody 后台返回的数据展示  
  38.                    "foot":true,                                                     // true/false  是否显示tfoot --- 默认false  
  39.                    "displayNum": 10,                                                //必须   默认 10  每页显示行数  
  40.                    "groupDataNum":6,                                                //可选    默认 10  组数  
  41.                    sort:false,                                                      // 点击表头是否排序 true/false  --- 默认false  
  42.                    search:false,                                                    // 默认为false 没有搜索  
  43.                    lang:{  
  44.                        gopageButtonSearchText:"搜索"  
  45.                    }  
  46.            }  
  47.            var cs = new KingTable(null,userOptions);  
  48.        }  
  49.    });   

3、ajax方法参数中不指定dataType,后台设置返回类型为"application/json"。这样jquery就会根据mime类型来智能判断,并自动解析成json对象

[java]  view plain  copy
  1. //Java代码:后台获取单个数控定位器的历史表格的数据  
  2. public void getHistorySingleData() throws IOException{  
  3.     HttpServletRequest request = ServletActionContext.getRequest();  
  4.     HttpServletResponse response = ServletActionContext.getResponse();  
  5.     response.setHeader("Content-type""text/html;charset=UTF-8");  
  6.     response.setContentType("application/json;charset=utf-8");  
  7.     String deviceName = request.getParameter("deviceName");  
  8.     String startDate= request.getParameter("startDate");  
  9.     String endDate = request.getParameter("endDate");  
  10.     SingleHistoryData[] singleHistoryData = chartService.getHistorySingleData(deviceName,startDate, endDate);  
  11.     System.out.println(singleHistoryData.length);  
  12.     System.out.println(JSONArray.fromObject(singleHistoryData).toString());//打印:[{"time":"2016-11-11 10:00:00","state":"运行","ball":"锁紧",....},{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....},{},{}....]查到几条singleHistoryData对象就打印几个对象的信息{"time":"2016-11-11 10:00:05","state":"运行","ball":"锁紧",....}  
  13.     response.getWriter().print(JSONArray.fromObject(singleHistoryData).toString());  
  14. }  

[javascript]  view plain  copy
  1.   /*js代码:页面首次加载时,显示规定时间段的数据*/   
  2. var data1 = [];  
  3. var deviceName=$("body").attr("id");   
  4.    var startDate = $("#startDate").val("2000-01-01 00:00:00");  
  5.    var endDate = $("#endDate").val("2018-01-01 00:00:00");  
  6.    $.ajax({  
  7.       url:"/avvii/chart/getHistorySingleData",  
  8.       type:"post",  
  9.       data:{  
  10.           "deviceName":deviceName,  
  11.           "startDate""2000-01-01 00:00:00",  
  12.           "endDate""2018-01-01 00:00:00"  
  13.       },  
  14.       success: function (data) {  
  15.        alert(data);//---->弹出[object Object],[object Object],[object Object][object Object],[object Object],[object Object]……后台传过来几条singleHistoryData对象就打印几个json对象:[object Object]  
  16.           for(var i = 0; i < data.length; i++){                          
  17.                 var name  = data[i]['time'];  
  18.                 var state = data[i]['state'];  
  19.                 var ball  = data[i]['ball'];  
  20.                 var xd    = data[i]['xd'];  
  21.                 var yd    = data[i]['yd'];  
  22.                 var zd    = data[i]['zd'];  
  23.                 var xf    = data[i]['xf'];  
  24.                 var yf    = data[i]['yf'];  
  25.                 var zf    = data[i]['zf'];  
  26.                    data1[i] = {name:name,state:state,ball:ball,xd:xd,yd:yd,zd:zd,xf:xf,yf:yf,zf:zf};  
  27.           }  
  28.        if(data.length != 10){  
  29.            for(var j=0;j<(10-((data.length)%10));j++){               //补全最后一页的空白行,使表格的长度保持不变  
  30.                data1[j+data.length] = {name:" ",state:"",ball:"",xd:"",yd:"",zd:"",xf:"",yf:"",zf:""};   
  31.            }  
  32.        }  
  33.           var userOptions = {  
  34.                   "id":"kingTable",                                             //必须 表格id  
  35.                   "head":["时间","运行状态","球头状态","X向位置/mm","Y向位置/mm","Z向位置/mm","X向承载力/Kg","Y向承载力/Kg","Z向承载力/Kg"],  //必须 thead表头  
  36.                   "body":data1,                                                 //必须 tbody 后台返回的数据展示  
  37.                   "foot":true,                                                      // true/false  是否显示tfoot --- 默认false  
  38.                   "displayNum": 10,                                                 //必须   默认 10  每页显示行数  
  39.                   "groupDataNum":6,                                                 //可选    默认 10  组数  
  40.                   sort:false,                                                       // 点击表头是否排序 true/false  --- 默认false  
  41.                   search:false,                                                     // 默认为false 没有搜索  
  42.                   lang:{  
  43.                       gopageButtonSearchText:"搜索"  
  44.                   }  
  45.           }  
  46.           var cs = new KingTable(null,userOptions);  
  47.       }  
  48.   });   

注意:只要前台或者后台有一处设置了返回json对象,就无需使用eval()方法或$.parseJSON()方法解析了,再解析就出错。

总结:以上几种方式,推荐使用第二种方式,方便且不易出错。

 

五.eval()方法

 var json对象=eval('('+json数据+')');大括号括起来的内容被eval()执行后返回的是一个JSON对象。

eval函数的工作原理:eval函数会评估一个给定的含有JavaScript代码的字符串,并且试图去执行包含在字符串里的表达式或者一系列的合法的JavaScript语句。eval函数将把最后一个表达式或者语句所包含的值或引用作为返回值。

为什么要 eval这里要添加 “("("+data+")");//”呢?

原因在于:eval本身的问题。 由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始和结束标记,那么{}将会被认为是执行了一句空语句。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值