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


Posted in Javascript onJanuary 31, 2018

一.什么是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数据的几种方式总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
取得父标签
Nov 14 Javascript
js 数组操作代码集锦
Apr 28 Javascript
jquery自定义下拉列表示例
Apr 25 Javascript
火狐下input焦点无法重复获取问题的解决方法
Jun 16 Javascript
限制上传文件大小和格式的jQuery插件实例
Jan 24 Javascript
JavaScript中的函数模式详解
Feb 11 Javascript
简单的JS时钟实例讲解
Jan 13 Javascript
javascript事件委托的用法及其好处简析
Apr 04 Javascript
利用node.js搭建简单web服务器的方法教程
Feb 20 Javascript
浅谈js中的this问题
Aug 31 Javascript
vue实现移动端H5数字键盘组件使用详解
Aug 25 Javascript
vue data有值,但是页面{{}} 取不到值的解决
Nov 09 Javascript
微信小程序模板(template)使用详解
Jan 31 #Javascript
浅谈MUI框架中加载外部网页或服务器数据的方法
Jan 31 #Javascript
js保留两位小数方法总结
Jan 31 #Javascript
微信小程序icon组件使用详解
Jan 31 #Javascript
详解Chai.js断言库API中文文档
Jan 31 #Javascript
微信小程序 如何引入外部字体库iconfont的图标
Jan 31 #Javascript
详解Vue单元测试Karma+Mocha学习笔记
Jan 31 #Javascript
You might like
php adodb连接带密码access数据库实例,测试成功
2008/05/14 PHP
php安全之直接用$获取值而不$_GET 字符转义
2012/06/03 PHP
php全排列递归算法代码
2012/10/09 PHP
微信公众号模板消息群发php代码示例
2016/12/29 PHP
PHP常用字符串函数用法实例总结
2020/06/04 PHP
jQuery 位置插件
2008/12/25 Javascript
用方法封装javascript的new操作符(一)
2010/12/25 Javascript
用JS判断IE版本的代码 超管用!
2011/08/09 Javascript
jQuery实现的文字hover颜色渐变效果实例
2016/02/20 Javascript
Google Maps基础及实例解析
2016/08/06 Javascript
JavaScript面向对象分层思维全面解析
2016/11/22 Javascript
浅析js的模块化编写 require.js
2016/12/07 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
2017/08/17 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
Node.js assert断言原理与用法分析
2019/01/04 Javascript
详解用JS添加和删除class类名
2019/03/25 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
2020/11/16 Javascript
[05:05]DOTA2亚洲邀请赛 战队出场仪式
2015/02/07 DOTA
python实现网页链接提取的方法分享
2014/02/25 Python
python utc datetime转换为时间戳的方法
2019/01/15 Python
python使用 request 发送表单数据操作示例
2019/09/25 Python
Python3 Tkinkter + SQLite实现登录和注册界面
2019/11/19 Python
python中if嵌套命令实例讲解
2021/02/25 Python
美国钻石商店:Zales
2016/11/20 全球购物
在阿联酋购买翻新手机和平板电脑:Teckzu
2021/02/12 全球购物
酒店管理专业毕业生推荐信
2013/11/10 职场文书
《要下雨了》教学反思
2014/02/17 职场文书
仓库主管岗位职责
2014/03/02 职场文书
周年庆典主持词
2014/04/02 职场文书
创建文明城市标语
2014/06/16 职场文书
单位工作证明
2014/10/07 职场文书
2014年小学教学工作总结
2014/11/13 职场文书
2016年入党心得体会范文
2016/01/23 职场文书
Python基础之赋值,浅拷贝,深拷贝的区别
2021/04/30 Python
matplotlib如何设置坐标轴刻度的个数及标签的方法总结
2021/06/11 Python
Java Socket实现多人聊天系统
2021/07/15 Java/Android