ajax通常是获取服务端的JSON格式数据

  • 作者:KK

  • 发表日期:2017.7.16


ajax主要就是为了拿数据,其实还要纠结一下:它拿的到底是啥数据啊

正如文章题目所说,拿的就是JSON数据,在《PHP基础 - 起步 - JSON》我大概讲过一下JSON,你自己也可以上网查一下“JSON入门”的学习资料

无论服务端是PHP还是JAVA还是Python什么的,它们往往都是给ajax返回JSON,但本文其实主要想讲一下如何在前端JS代码处理返回JS的事情


基本示例

JS代码:

$.ajax({
	url : 'data.json',
	success : function(数据){
		console.log(数据.age);
		console.log(数据.name);
	}
});

相同目录下建一个data.json(文件后缀必须 .json),文件内容如下:

{
	"age":18,
	"name":"Jay"
}

这样运行JS代码后会请求这个json文件里的数据,这些数据就是按照JSON格式写的

但你要发现一下其实它们跟JS的对象写法很像,JS的对象是这样写的:

var a = {
	age : 11,
	name : 'Jay'
};

alert(a.age);
alert(a.name);

所以JSON跟JS的对象天然地互相兼容,JSON字符串{"age":18,"name":"Jay"}跟JS对象{age:18,name:"Jay"}就是这样兼容过来的,而JS的对象属性本身也可以用双引号包住


复杂点的JSON

这回将data.json文件里的内容改成这样:

{
	"age":18,
	"name":"Jay",
	"childs":[
		"aaa",
		"bbb"
	]
}

然后JS测试代码:

$.ajax({
	url : 'data.json',
	success : function(数据){
		console.log(数据.childs.length); //childs的元素个数
		for(var i in 数据.childs){
			console.log(数据.childs[i]); //里面的第1个元素
		}
	}
});

以上的JSON里面嵌套了一个数组,增加这个示例是为了让大家进一步了解JSON在前端的处理


Content-type为application/json的时候会自动转换JSON字符串为对象

上面测试json数据时是使用data.json这个文件名,可是如果你改成data.txt,文件内容不用改,再次请求这个data.txt地址,在回调里访问数据.childs.length会出错,因为它不是一个对象,你再试一下typeof(数据)测试一下变量类型,它会告诉你是string,怎么会这样呢?

首先你要明确一点:JSON本身只是一段文本,一个字符串,只是有特定的编排规则,那么ajax请求下来的其实也就是一个字符串,一个字符串怎么会有对象、数组这些内容呢

其实服务器发现被请求的地址是json后缀时,它除了将JSON字符串发送给浏览器,还发送了一个叫做Content-type的信息(HTTP响应头,见下图)

上图可见Content-type的值是application/json,然后是jQuery就接收到了这个信息,自动将服务器的返回数据转换成JS的对象了

但是如果文件名为data.txt的时候,服务器响应回来的Content-type却变成了text/plain,于是jQuery认为“哦,服务器发回来的仅仅是一片文本,我不管它,原样传递给callback吧”


非json后缀的地址返回响应application/json

实际上往往ajax请求数据的地址都不是json后缀,比如xxx.php、xxx.do、xxx.jsp、xxx.apsx这些

比方说data.php这样吧,我们需要往这个地址获取JSON,如果它直接echo '{"name":"Jay"}',jQuery也会认为是一段文本,不信你看看调试器显示的Content-type,它很可能是text/html而不是application/json

那怎么办呢,难道不用PHP后缀作为请求地址吗?甚至还有其它编程语言呢

其实PHP可以这样做:

header('Content-type:application/json'); //声明返回的数据是JSON,这样jQuery就会去转换成对象了
echo '{"name":"Jay"}';

而无论服务端怎么实现,这都是服务端要做好的事情:在返回JSON数据时,将Content-type设置为application/json


不靠服务端的Content-type其实也可以,自己声明

前端发ajax请求的时候声明dataType是json就好了

$.ajax({
	url : 'data.php',
	dataType : 'json',
	success : function(数据){
		console.log(数据.name);
	}
});

这样jQuery会无视服务端返回的类型,按照前端代码声明的类型来自动转换JSON字符串(前提是服务端会返回一个有效的可以转换的JSON字符串)