欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于$.ajax()方法从服务器获取json数据的几种方式总结

程序员文章站 2022-07-04 23:40:49
一.什么是json json是一种取代xml的数据结构,和xml相比,它更小巧但描述能力却很强,网络传输数据使用流量更少,速度更快。 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为例解释,下面三中方式的结果都是图一所示,项目运行在内网,无法截图,只能拍照,见谅。

基于$.ajax()方法从服务器获取json数据的几种方式总结

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

//java代码:后台获取单个数控定位器的历史表格的数据
	public void gethistorysingledata() throws ioexception{
		httpservletrequest request = servletactioncontext.getrequest();
		httpservletresponse response = servletactioncontext.getresponse();
		response.setheader("content-type", "text/html;charset=utf-8");
		response.setcontenttype("text/html;charset=utf-8");
		string devicename = request.getparameter("devicename");
		string startdate= request.getparameter("startdate");
		string enddate = request.getparameter("enddate");
		singlehistorydata[] singlehistorydata = chartservice.gethistorysingledata(devicename,startdate, enddate);
		system.out.println(singlehistorydata.length);
		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":"锁紧",....}
		response.getwriter().print(jsonarray.fromobject(singlehistorydata).tostring());
	}
	/*js代码:选择查询某一时间段的数据,点击查询之后进行显示*/
 $("#search").click(function () {
 	var data1 = [];
 	var n;
 	var devicename=$("body").attr("id"); 
  var startdate = $("#startdate").val();
  var enddate = $("#enddate").val();
  $.ajax({
   url:"/avvii/chart/gethistorysingledata",
   type:"post",
   data:{
    "devicename":devicename,
    "startdate": startdate,
    "enddate": enddate
   },
   success: function (data) {
  	 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":"锁紧",....}
 		 alert(object.prototype.tostring.call(data)); //--->弹出[object string],说明获取的是string类型的数据
  	 var jsonobjs = eval("(" + data + ")");  //或者:var jsonobjs = $.parsejson(data);
 		 alert(jsonobjs);//alert(jsonobjs);---->弹出[object object],[object object],[object object][object object],[object object],[object object]……后台传过来几条singlehistorydata对象就打印几个[object object]
    n=jsonobjs.length;
    if(n==0){
   	 alert("您选择的时间段无数据,请重新查询");
    }
 		 for(var i = 0; i < jsonobjs.length; i++){	      
		  	  var name = jsonobjs[i]['time'];//针对每一条数据:jsonobjs[i],或者:jsonobjs[i].time
		 	  var state = jsonobjs[i]['state'];
		 	  var ball = jsonobjs[i]['ball'];
		 	  var xd = jsonobjs[i]['xd'];
		 	  var yd = jsonobjs[i]['yd'];
		 	  var zd = jsonobjs[i]['zd'];
		 	  var xf = jsonobjs[i]['xf'];
		 	  var yf = jsonobjs[i]['yf'];
		 	  var zf = jsonobjs[i]['zf'];
      data1[i] = {name:name,state:state,ball:ball,xd:xd,yd:yd,zd:zd,xf:xf,yf:yf,zf:zf};//个数与下面表头对应起来就可以了,至于叫什么名字并不影响控件的使用
    }
 		 if(jsonobjs.length != 10){
 			 for(var j=0;j<(10-((jsonobjs.length)%10));j++){    //补全最后一页的空白行,使表格的长度保持不变
 				 data1[j+jsonobjs.length] = {name:" ",state:"",ball:"",xd:"",yd:"",zd:"",xf:"",yf:"",zf:""}; 
 			 }
 		 }
    var useroptions = {
      "id":"kingtable",        				//必须 表格id
      "head":["时间","运行状态","球头状态","x向位置/mm","y向位置/mm","z向位置/mm","x向承载力/kg","y向承载力/kg","z向承载力/kg"], //必须 thead表头
      "body":data1,         				//必须 tbody 后台返回的数据展示
      "foot":true,         					// true/false 是否显示tfoot --- 默认false
      "displaynum": 10,        					//必须 默认 10 每页显示行数
      "groupdatanum":6,        					//可选 默认 10 组数
      sort:false,         					// 点击表头是否排序 true/false --- 默认false
      search:false,         					// 默认为false 没有搜索
      lang:{
       gopagebuttonsearchtext:"搜索"
      }
    }
    var cs = new kingtable(null,useroptions);
   }
  }); 
 });

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

	//java代码:后台获取单个数控定位器的历史表格的数据
	public void gethistorysingledata() throws ioexception{
		httpservletrequest request = servletactioncontext.getrequest();
		httpservletresponse response = servletactioncontext.getresponse();
		response.setheader("content-type", "text/html;charset=utf-8");
		response.setcontenttype("text/html;charset=utf-8");
		string devicename = request.getparameter("devicename");
		string startdate= request.getparameter("startdate");
		string enddate = request.getparameter("enddate");
		singlehistorydata[] singlehistorydata = chartservice.gethistorysingledata(devicename,startdate, enddate);
		system.out.println(singlehistorydata.length);
		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":"锁紧",....}
		response.getwriter().print(jsonarray.fromobject(singlehistorydata).tostring());
	}
/*js代码:页面首次加载时,显示规定时间段的数据*/ 
	var data1 = [];
	var devicename=$("body").attr("id"); 
 var startdate = $("#startdate").val("2000-01-01 00:00:00");
 var enddate = $("#enddate").val("2018-01-01 00:00:00");
 $.ajax({
  url:"/avvii/chart/gethistorysingledata",
  type:"post",
  data:{
   "devicename":devicename,
   "startdate": "2000-01-01 00:00:00",
   "enddate": "2018-01-01 00:00:00"
  },
  datatype:"json",
  success: function (data) {
 	 alert(data);//---->弹出[object object],[object object],[object object][object object],[object object],[object object]……后台传过来几条singlehistorydata对象就打印几个json对象:[object object]
   for(var i = 0; i < data.length; i++){	      
	  	  var name = data[i]['time'];
	 	  var state = data[i]['state'];
	 	  var ball = data[i]['ball'];
	 	  var xd = data[i]['xd'];
	 	  var yd = data[i]['yd'];
	 	  var zd = data[i]['zd'];
	 	  var xf = data[i]['xf'];
	 	  var yf = data[i]['yf'];
	 	  var zf = data[i]['zf'];
     data1[i] = {name:name,state:state,ball:ball,xd:xd,yd:yd,zd:zd,xf:xf,yf:yf,zf:zf};
   }
		 if(data.length != 10){
			 for(var j=0;j<(10-((data.length)%10));j++){    //补全最后一页的空白行,使表格的长度保持不变
				 data1[j+data.length] = {name:" ",state:"",ball:"",xd:"",yd:"",zd:"",xf:"",yf:"",zf:""}; 
			 }
		 }
   var useroptions = {
     "id":"kingtable",        				//必须 表格id
     "head":["时间","运行状态","球头状态","x向位置/mm","y向位置/mm","z向位置/mm","x向承载力/kg","y向承载力/kg","z向承载力/kg"], //必须 thead表头
     "body":data1,         				//必须 tbody 后台返回的数据展示
     "foot":true,         					// true/false 是否显示tfoot --- 默认false
     "displaynum": 10,        					//必须 默认 10 每页显示行数
     "groupdatanum":6,        					//可选 默认 10 组数
     sort:false,         					// 点击表头是否排序 true/false --- 默认false
     search:false,         					// 默认为false 没有搜索
     lang:{
      gopagebuttonsearchtext:"搜索"
     }
   }
   var cs = new kingtable(null,useroptions);
  }
 }); 

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

	//java代码:后台获取单个数控定位器的历史表格的数据
	public void gethistorysingledata() throws ioexception{
		httpservletrequest request = servletactioncontext.getrequest();
		httpservletresponse response = servletactioncontext.getresponse();
		response.setheader("content-type", "text/html;charset=utf-8");
		response.setcontenttype("application/json;charset=utf-8");
		string devicename = request.getparameter("devicename");
		string startdate= request.getparameter("startdate");
		string enddate = request.getparameter("enddate");
		singlehistorydata[] singlehistorydata = chartservice.gethistorysingledata(devicename,startdate, enddate);
		system.out.println(singlehistorydata.length);
		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":"锁紧",....}
		response.getwriter().print(jsonarray.fromobject(singlehistorydata).tostring());
	}
 /*js代码:页面首次加载时,显示规定时间段的数据*/ 
	var data1 = [];
	var devicename=$("body").attr("id"); 
 var startdate = $("#startdate").val("2000-01-01 00:00:00");
 var enddate = $("#enddate").val("2018-01-01 00:00:00");
 $.ajax({
  url:"/avvii/chart/gethistorysingledata",
  type:"post",
  data:{
   "devicename":devicename,
   "startdate": "2000-01-01 00:00:00",
   "enddate": "2018-01-01 00:00:00"
  },
  success: function (data) {
 	 alert(data);//---->弹出[object object],[object object],[object object][object object],[object object],[object object]……后台传过来几条singlehistorydata对象就打印几个json对象:[object object]
   for(var i = 0; i < data.length; i++){	      
	  	  var name = data[i]['time'];
	 	  var state = data[i]['state'];
	 	  var ball = data[i]['ball'];
	 	  var xd = data[i]['xd'];
	 	  var yd = data[i]['yd'];
	 	  var zd = data[i]['zd'];
	 	  var xf = data[i]['xf'];
	 	  var yf = data[i]['yf'];
	 	  var zf = data[i]['zf'];
     data1[i] = {name:name,state:state,ball:ball,xd:xd,yd:yd,zd:zd,xf:xf,yf:yf,zf:zf};
   }
		 if(data.length != 10){
			 for(var j=0;j<(10-((data.length)%10));j++){    //补全最后一页的空白行,使表格的长度保持不变
				 data1[j+data.length] = {name:" ",state:"",ball:"",xd:"",yd:"",zd:"",xf:"",yf:"",zf:""}; 
			 }
		 }
   var useroptions = {
     "id":"kingtable",        				//必须 表格id
     "head":["时间","运行状态","球头状态","x向位置/mm","y向位置/mm","z向位置/mm","x向承载力/kg","y向承载力/kg","z向承载力/kg"], //必须 thead表头
     "body":data1,         				//必须 tbody 后台返回的数据展示
     "foot":true,         					// true/false 是否显示tfoot --- 默认false
     "displaynum": 10,        					//必须 默认 10 每页显示行数
     "groupdatanum":6,        					//可选 默认 10 组数
     sort:false,         					// 点击表头是否排序 true/false --- 默认false
     search:false,         					// 默认为false 没有搜索
     lang:{
      gopagebuttonsearchtext:"搜索"
     }
   }
   var cs = new kingtable(null,useroptions);
  }
 }); 

注意:只要前台或者后台有一处设置了返回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代码块的开始和结束标记,那么{}将会被认为是执行了一句空语句。

以上这篇基于$.ajax()方法从服务器获取json数据的几种方式总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。