基于$.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 相关文章推荐
javascript 客户端验证上传图片的大小(兼容IE和火狐)
Aug 15 Javascript
完美解决AJAX跨域问题
Nov 01 Javascript
jquery移除、绑定、触发元素事件使用示例详解
Apr 10 Javascript
JavaScript实现找出字符串中第一个不重复的字符
Sep 03 Javascript
理解jquery事件冒泡
Jan 03 Javascript
jQuery组件easyui基本布局实现代码
Aug 25 Javascript
js实现文字超出部分用省略号代替实例代码
Sep 01 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
Sep 11 Javascript
PHP 实现一种多文件上传的方法
Sep 20 Javascript
vue 下列表侧滑操作实例代码详解
Jul 24 Javascript
Javascript中弹窗confirm与prompt的区别
Oct 26 Javascript
vue element table中自定义一些input的验证操作
Jul 18 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 include的妙用,实现路径加密
2008/07/29 PHP
PHP获取ip对应地区和使用网络类型的方法
2015/03/11 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
线路分流自动跳转代码;希望对大家有用!
2006/12/02 Javascript
javascript确认框的三种使用方法
2013/12/17 Javascript
Jquery方式获取iframe页面中的 Dom元素
2014/05/07 Javascript
javascript在网页中实现读取剪贴板粘贴截图功能
2014/06/07 Javascript
一波JavaScript日期判断脚本分享
2016/03/06 Javascript
jquery拖动层效果插件用法实例分析(附demo源码)
2016/04/28 Javascript
Javascript之BOM(window对象)详解
2016/05/25 Javascript
jQuery动态创建元素以及追加节点的实现方法
2016/10/20 Javascript
bootstarp modal框居中显示的实现代码
2017/02/18 Javascript
微信小程序 PHP生成带参数二维码
2017/02/21 Javascript
如何编写jquery插件
2017/03/29 jQuery
ES6新特性六:promise对象实例详解
2017/04/21 Javascript
如何在AngularJs中调用第三方插件库
2017/05/21 Javascript
Nodejs 和Session 原理及实战技巧小结
2017/08/25 NodeJs
使用pkg打包Node.js应用的方法步骤
2018/10/19 Javascript
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
[02:32]DOTA2完美大师赛场馆静安体育中心观赛全攻略
2017/11/08 DOTA
深入学习Python中的装饰器使用
2016/06/20 Python
基于Python实现的ID3决策树功能示例
2018/01/02 Python
python如何制作缩略图
2019/04/30 Python
Django REST框架创建一个简单的Api实例讲解
2019/11/05 Python
Python configparser模块封装及构造配置文件
2020/08/07 Python
详解pandas映射与数据转换
2021/01/22 Python
世界顶级户外运动品牌折扣网站:LeftLane Sports
2019/06/12 全球购物
英国景点门票网站:attractiontix
2019/08/27 全球购物
大家访活动实施方案
2014/03/10 职场文书
《第一朵杏花》教学反思
2014/04/16 职场文书
迎七一演讲稿
2014/09/12 职场文书
县委常委班子专题民主生活会查摆问题及整改措施
2014/09/27 职场文书
2014党的群众路线教育实践活动总结报告
2014/10/31 职场文书
工作失职检讨书
2015/01/26 职场文书
会计求职自荐信
2015/03/26 职场文书
国际最新研究在陨石中发现DNA主要成分 或由陨石带来地球
2022/04/29 数码科技