基于$.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 相关文章推荐
神奇的7个jQuery 3D插件整理
Jan 06 Javascript
jQuery操作select的实例代码
Jun 14 Javascript
详解JS中Array对象扩展与String对象扩展
Jan 07 Javascript
js+canvas简单绘制圆圈的方法
Jan 28 Javascript
JS焦点图,JS 多个页面放多个焦点图的实例
Dec 08 Javascript
javaScript实现滚动条事件详解
Mar 24 Javascript
JavaScript实现全选取消效果
Dec 14 Javascript
js中el表达式的使用和非空判断方法
Mar 28 Javascript
JavaScript事件冒泡与事件捕获实例分析
Aug 01 Javascript
jQuery实现的页面弹幕效果【测试可用】
Aug 17 jQuery
vue中子组件的methods中获取到props中的值方法
Aug 27 Javascript
layer插件实现在弹出层中弹出一警告提示并关闭弹出层的方法
Sep 24 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
基于OpenCV的PHP图像人脸识别技术
2009/10/11 PHP
php使用glob函数遍历文件和目录详解
2016/09/23 PHP
Laravel 前端资源配置教程
2019/10/18 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
入门基础学习 ExtJS笔记(一)
2010/11/11 Javascript
JavaScript用select实现日期控件
2015/07/17 Javascript
javascript时间差插件分享
2016/07/18 Javascript
深入理解JavaScript中Ajax
2016/08/02 Javascript
JavaScript性能优化总结之加载与执行
2016/08/11 Javascript
微信小程序 在Chrome浏览器上运行以及WebStorm的使用
2016/09/27 Javascript
BootStrap 实现各种样式的进度条效果
2016/12/07 Javascript
Vue.js学习教程之列表渲染详解
2017/05/17 Javascript
JS FormData上传文件的设置方法
2017/07/05 Javascript
JS对象与JSON互转换、New Function()、 forEach()、DOM事件流等js开发基础小结
2017/08/10 Javascript
微信小程序异步API为Promise简化异步编程的操作方法
2018/08/14 Javascript
详解Puppeteer前端自动化测试实践
2019/02/21 Javascript
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
python 删除列表里所有空格项的方法总结
2018/04/18 Python
Selenium的使用详解
2018/10/19 Python
浅析Python 中几种字符串格式化方法及其比较
2019/07/02 Python
python time.sleep()是睡眠线程还是进程
2019/07/09 Python
Python aiohttp百万并发极限测试实例分析
2019/10/26 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
2020/09/16 Python
python之pygame模块实现飞机大战完整代码
2020/11/29 Python
Python3使用tesserocr识别字母数字验证码的实现
2021/01/29 Python
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
servlet面试题
2012/08/20 面试题
土木工程实习生自我鉴定
2013/09/19 职场文书
旅游管理专业学生求职信
2013/09/28 职场文书
《美丽的黄昏》教学反思
2014/02/28 职场文书
采购意向书范本
2014/03/31 职场文书
投标授权委托书范文
2014/08/02 职场文书
房屋租赁合同解除协议书
2014/10/11 职场文书
银行客户经理岗位职责
2015/04/09 职场文书
2015年高三年级组工作总结
2015/07/21 职场文书
pandas时间序列之pd.to_datetime()的实现
2022/06/16 Python