频道栏目
首页 > 资讯 > JavaScript > 正文

js笔记--JSON,Ajax

16-07-29        来源:[db:作者]  
收藏   我要投稿

1.JSON语法

JSON是一种数据格式,并不是一种编程语言。虽然与JavaScript具有相同的语法形式,但JSON并不从属于JavaScript。 JSON不支持变量,函数或对象实例,它就是一种表示结构化数据的格式

1.语法

简单值: 字符串,数值,布尔和null。不支持JavaScript中的特殊值undefined对象:作为复杂数据类型,表示的是一组有序的键值对。每个键值对的值可以是简单类型也可以是复杂类型数组:表示一组有序的值的列表,可以通过数值索引来访问其中的值 JSON字符串必须使用双引号(单引号会导致语法错误)

2.对象

JSON中对象与JavaScript字面量稍微有一些不同

JavaScript中的对象字面量:

 

	var person = {
		name:"ethan",
		age:25
	};
JSON对象:

 

 

	{
		"name":"ethan",
		"age":28
	}
对象的属性必须加双引号

 

3.数组

JavaScript数组:
var values = [25,"hi",true];
JSON数组:

 

	[25,"hi",true]

 

2.解析与序列化

1.JSON对象

早期使用eval()函数解析并返回JavaScript对象。 现在通过JSON全局对象来解析json
stringify():
将JavaScript对象序列化为JSON字符串
parse():
将JSON字符串解析为原生JavaScript值

在序列化JavaScript对象时,所有函数及原型成员都会被忽略。此外,值为undefined的任何属性也会被跳过。结果中最终都是值为有效JSON数据类型的实例属性。

2.序列化选项

JSON.stringify()除了接收要序列化的JavaScript对象外,还可以接收另外两个参数。一:过滤器,可以是一个数组,也可以是一个函数;二:一个选项,表示 是否在JSON字符串中保留缩进。

1.过滤结果

如果过滤器参数是数组,那么JSON.stringify()的结果中将只包含数组中列出的属性

 

	var person = {
		name:"zhangsan",
		"age":34,
		"hobbit":["football","basketball",'volleyball'],
		son:{
			name:"李四",
			age:10
		}
	};

	var json = JSON.stringify(person,["name","age"]);
	console.log(json);// {"name":"zhangsan","age":34}

 

如果过滤参数是函数

	var json = JSON.stringify(person,function(key,value){
		switch(key){
			case "name":
				return value;
			case "age":
				return undefined;//跳过指定的属性
			case "hobbit":
				return value.join(",");
			default:
				return value;
		}
	});
	console.log(json);// {"name":"zhangsan","hobbit":"football,basketball,volleyball","son":{"name":"李四"}}

2.字符串缩进

JSON.stringify()方法的第三个参数控制结果中的缩进和空白符。
	var person = {
		name:"zhangsan",
		"age":29,
		hobbit:["basketball","sing","eat"],
		son:{
			name:"lisi",
			age:4
		}
	};
	var json = JSON.stringify(person,null,2);
	console.log(json);
输出格式如下:
{
  "name": "zhangsan",
  "age": 29,
  "hobbit": [
    "basketball",
    "sing",
    "eat"
  ],
  "son": {
    "name": "lisi",
    "age": 4
  }
}

最大缩进空格数为10,超过10就取10

缩进字符串参数: 自负串替代空格

 

		var json = JSON.stringify(person,null,"- -");
		console.log(json);
{
- -"name": "zhangsan",
- -"age": 29,
- -"hobbit": [
- -- -"basketball",
- -- -"sing",
- -- -"eat"
- -],
- -"son": {
- -- -"name": "lisi",
- -- -"age": 4
- -}
}

 

3.toJSON()方法

有时候JSON.stringify()并不能满足对某些对象进行自定义序列化的需求。这种情况下,可以通过对象上调用toJSON()方法,返回自身的JSON数据格式。原生Date对象有一个toJSON()方法,将JavaScript的Date对象自动转换成ISO 8601日期字符串(与Date上调用toISOString()结果一样)。

	var person = {
		name:"zhangsan",
		"age":34,
		"hobbit":["football","basketball",'volleyball'],
		son:{
			name:"李四",
			age:10
		},
		toJSON:function(){ //自定义json转换方法
			return this.name;
		}
	};
	var jsonText = JSON.stringify(person);
	console.log(jsonText); //zhangsan

toJSON()可以作为函数过滤器的补充,对象序列化顺序如下:

 

如果存在toJSON()方法且能通过它取得有效的值,则调用该方法。否则,按默认顺序执行序列化如果提供了第二个参数,应用这个函数过滤器。传入函数过滤器的值是第(1)步返回的值对第(2)步返回的值进行序列化如果提供了第三个参数,执行相应的格式化

 

3.解析选项

JSON.parse()方法可以接受一个参数,该参数是一个函数,在每个键值对上调用。称为(reviver)还原函数

如果函数返回undefined,表示从结果中删除相应的键;如果返回其他值,表示将该值插入到结果中。

	var person = {
		name:"zhangsan",
		"age":34,
		"hobbit":["football","basketball",'volleyball'],
		son:{
			name:"李四",
			age:10
		},
		birthday:new Date(2016,6,8)
	};
	var jsonText = JSON.stringify(person);
	console.log(jsonText);
	var personCopy = JSON.parse(jsonText,function(key,value){
		if(key == 'birthday'){ //否则返回日期字符串
			return new Date(value);
		}else{
			return value;
		}
	});
	console.log(personCopy);

3.XMLHttpReques对象

1.XHR用法

open():接收三个参数,请求方式(get,post等),请求URL,是否异步发送请求
并不会真正发送请求,只是启动一个请求以备发送。只能向同一个域中使用相同端口和协议的URL发送请求。

send():发送请求,一个参数(要发送的请求数据)。在收到响应后,响应的数据会自动填充XHR对象的属性 responseText:作为响应主体被返回的文本,无论内容类型是什么。responseXML:如果响应内容是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的XML DOM文档。status:响应的HTTP状态statusText:HTTP状态说明
	var xhr = new XMLHttpRequest();
	// console.log(xhr);
	xhr.open("post","....url...",false);
	xhr.send(null);
	if((xhr.status >=200 && xhr.status<300)||xhr.status ==304){
		// console.log(xhr.responseText);
		console.log(xhr.status);
	}else{
		console.log("request fail");
	}

发送异步请求(JS继续执行不必等待响应)。通过检测XHR的readyState属性来判断响应状态 0:未初始化,尚未调用open()方法1:启动。已经调用open()方法2:发送。已经调用send()方法3:接收。已经接收到部分响应数据4:完成。已经接收到全部响应数据,可以在客户端使用 readyState属性值变化都会触发readystatechange事件。必须在open()方法调用前指定onreadystatechange事件处理程序才能保证跨浏览器兼容性。
	var xhr = new XMLHttpRequest();
	//检测状态变化
	xhr.onreadystatechange = function(){
		console.log(xhr.readyState);
		if(xhr.readyState == 4){//响应完成
			if((xhr.status >=200 && xhr.status<300)||xhr.status ==304){
				// console.log(xhr.responseText);
				console.log(xhr.status);
			}else{
				console.log("request fail");
			}
		}
	}
	// console.log(xhr);
	xhr.open("post",".....",false);
	xhr.send(null);
在接收响应之前可以调用abort()方法来取消异步请求 xhr.abort();

2.HTTP请求消息头

XHR提供setRequestHeader(key,value)来操作http请求消息头

 

Accept:浏览器能处理的内容类型Accept-Charset:浏览器能显示的字符集Accept-Encoding:浏览器能处理的压缩编码Accept-Language:浏览器当前设置的语言Connection:浏览器与服务器之间连接的类型Cookie:当前页面设置的任何CookieHost:发出请求的页面所在的域Referer:发出请求的页面URL(防止盗链)User-Agent:浏览器的用户代理字符串 必须在open()之后,send()之前调用setRequestHeader() getResponseHeader();获取响应头对应的信息 getAllResponseHeader():获取包含所有头部信息的长字符串
	var xhr = new XMLHttpRequest();
	//检测状态变化
	xhr.onreadystatechange = function(){
		console.log(xhr.readyState);
		if(xhr.readyState == 4){//响应完成
			if((xhr.status >=200 && xhr.status<300)||xhr.status ==304){
				var allHeaders = xhr.getAllResponseHeaders();
				console.log(allHeaders);
			}else{
				console.log("request fail");
			}
		}
	}
	xhr.open("post","wgps/tmsweb/showDomesticRoute.action?referenceCode=HTM201607170132201",false);
	xhr.setRequestHeader("MyHead","hehe");
	xhr.send(null);

 

3.get请求方式

 

查询字符串参数追加到URL末尾发送给服务器。对XHR而言,位于传入open()的URL末尾的查询字符串必须经过正确的编码才行 每个参数的名称和值都必须使用encodeURIComponent()进行编码
	function addURLParam(url,name,value){
		url += (url.indexOf("?")== -1 ? '?':'&');
		url += encodeURIComponent(name)+"="+encodeURIComponent(value);
		return url;
	}

 

4.post请求

 

send():向服务器发送数据,作为请求的主体提交。
由于XHR最初的设计主要是为了处理XML,因此可以传入XML DOM文档,传入的文档经序列化之后将作为请求主体被提交到服务器。当然,也可以在此传入任何想发送到服务器的字符串

 

默认情况下,服务器对POST请求和提交Web表单的请求不会一视同仁。因此服务器端必须有程序来读取发送过来的原始数据,并从中解析出有用的部分。

可以使用XHR模仿表单提交。将Content-Type头部信息设置为application/x-www-form-urlencoded(表单提交时的内容类型),然后提交表单序列化后的格式参数。

	xhr.open("post","....",true);
	xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	xhr.send(serialize(form));
与GET请求相比,POST请求消耗的资源会更多。从性能角度看,发送相同的数据,GET请求的速度最多可达到POST请求的两倍。

 

4.XMLHttpRequest 2级

1.FormData

FormData为序列化表单以及创建与表单格式相同的数据(用于通过XHR传输)提供了便利。

键值对

 

	var data = new FormData();
	data.append("name","zhangsan");
直接构造函数传入表单

 

 

	var data = new FormData(document.forms[0]);
不必设置请求头。XHR对象能识别传入的数据类型是FormData的实例

 

 

	xhr.send(new FormData(document.forms[0]));

 

2.超时设定

XHR对象timeout属性,请求在等待响应指定毫秒后就终止。如果在规定时间内没有接收到响应,就会触发timeout事件,进而调用ontimeout事件处理程序。

 

	var xhr = new XMLHttpRequest();
	//检测状态变化
	xhr.onreadystatechange = function(){
		console.log(xhr.readyState);
		if(xhr.readyState == 4){//响应完成
			try{
				if((xhr.status >=200 && xhr.status<300)||xhr.status ==304){
					var allHeaders = xhr.getAllResponseHeaders();
					console.log(allHeaders);
				}else{
					console.log("request fail");
				}
			}catch(err){
				console.log(err);
			}
		}
	}
	xhr.open("post","...",true);
	xhr.timeout = 1000;//将超时设置为1秒
	xhr.ontimeout = function(){
		console.log("请求超时");
	}
	xhr.send(null);
如果1秒钟内没有返回就会自动终止。readyState变为4,触发onreadystatechange事件处理程序。超时后再访问status属性,会导致报错。

 

所以将status检测的代码放到try-catch语句中

3.overrideMimeType()方法

用来重写XHR响应的MIME类型。必须在send()方法前

 

	xhr.overrideMimeType("text/xml");
	xhr.send(null);

 

5.进度事件

loadstart:接收到响应数据的第一个字节时触发progress:接收响应期间持续不断地触发error:请求发生错误时触发abort:在调用abort()方法终止连接时触发load:在接收到完整响应数据时触发loadend:在通信完成或触发error,abort或load时间后触发 从触发loadstart事件开始,接下来是一个或多个progress事件,然后触发error,abort或load事件中的一个,最后触发loadend事件结束

1.load事件

用来替代readystatechange事件,响应接收完毕后触发load事件,不用检查readyState属性。

而onload事件处理程序会接收到一个event对象,target属性就指向XHR对象实例

 

	var xhr = new XMLHttpRequest();
	xhr.onload = function(event){
		console.log(event.target);//XHR对象
		if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
			console.log("success"+xhr.status);
		}else{
			console.log("fail"+xhr.status);
		}
	}
	xhr.open("get","...",true);
	xhr.send(null);
只要浏览器接收到服务器响应。不管状态如何,都会触发load事件

 

2.progress事件

在浏览器接收新数据期间周期性地触发。onprogress事件处理程序会接收到一个event对象,target属性是XHR对象,包含三个额外属性:

lengthComputable:进度信息是否可用

position:已经接收的字节数

totalSize:根据Content-Length响应头消息确定的预期字节数

可以给用户创建一个进度指示器

 

	xhr.onprogress = function(event){
		var divStatus = document.getElementById("editDiv");
		if(event.lengthComputable){
			divStatus.innerHTML = "received"+event.position+" of " +event.totalSize +"bytes";
		}
	}
必须在调用open()方法之前添加onprogress事件处理程序

 

6.跨资源共享

CORS(Cross-Origin Resource Sharing,跨源资源共享),定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通。使用自定义HTTP头部让浏览器与服务器沟通。 比如一个简单的使用GET或POST发送的请求,没有自定义头部,主体内容是text/plain。在发送请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的资源信息(协议,域名,和端口),一般服务器根据这个头部信息来决定是否给予响应。 Origin:http://www.baidu.com
如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息(如果是公共资源,可以回发"*"). Access-Control-Allow-Origin:http://www.baidu.com
如果没有这个头部,或这个头部信息不匹配,浏览器会驳回请求。正常情况下,浏览器会处理请求,但请求和响应不包含cookie信息。
 

当使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据

 

1.IE对CORS的实现

XDR(XDomainRequest)。该对象与XHR类似。部分实现了CORS规范 cookie不会随请求发送,也不会随响应返回只能设置请求头中的Content-Type字段不能访问响应头部信息只支持GET和POST请求 所有XDR请求都是异步执行,请求返回后会触发load事件,响应数据保存在responseText属性。

2.其他浏览器对CORS的实现

Firefox3.5+,Safari4+,Chrome通过XMLHttpRequest对象实现了对CORS的原生支持,跨域访问不需要额外代码,在open()中传入绝对URL即可。
apache服务器 :http://localhost/ 上的html
	var xhr = new XMLHttpRequest();
	// console.log(xhr);
	xhr.onload = function(event){
		console.log(event.target);//XHR对象
		if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
			console.log(xhr.responseText);
		}else{
			console.log("fail"+xhr.status);
		}
	}
	xhr.open("post","http://localhost:8080/wgps/servlet/CROSServlet",false);//访问tomcat上的servlet
	xhr.send(null);
报错: XMLHttpRequest cannot load http://localhost:8080/wgps/servlet/CROSServlet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. 在tomcat服务器端,设置响应消息头的属性
response.setHeader("Access-Control-Allow-Origin", "http://localhost");

就可以正常实现跨域访问

XHR对象可以访问status和statusText属性,并且支持同步请求。同时也有如下限制:

 

不能使用setRequestHeader()设置自定义头部不能发送和接收cookie调用getAllResponseHeaders()方法总会返回空字符串 在访问本地资源时,最好使用相对URL,避免出现限制访问头部或本地cookie信息等问题。

 

3.Preflighted Requests

CORS通过Preflighted Requests的透明服务器验证机制支持开发人员使用自定义的头部,GET或POST之外的方法,以及不同类型的主体内容。 向服务器发送一个Preflight请求,这种请求使用OPTIONS方法。 Origin:与简单请求相同。Access-Control-Request-Method:请求自身使用的方法Access-Control-Request-Headers:(可选)自定义的头部信息,多个信息以逗号分隔。

7.其他跨域技术

在CORS出现以前,要实现跨域Ajax通信颇费一些周折。利用DOM中能够执行跨域请求的功能,在不依赖XHR对象的情况下也能发送某种请求。

1.图像Ping

使用标签。一个网页可以从任何网页中加载图像,不用担心跨域问题。这也是在线广告跟踪浏览量的主要方式。可以动态地创建图像,使用它们的onload和onerror事件处理程序来确定是否接收到了响应。

动态创建图像经常用于图像Ping。图像Ping是与服务器进行简单,单向的跨域通信的一种方式。

请求的数据通过查询字符串形式发送,响应可以是任意内容,通常是像素图或204响应。

通过图像Ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,能知道响应是什么时候接收到的

 

	var img  = new Image();
	img.onload  = function(){
		console.log("done!");
	}
	img.onerror = function(){
		console.log("error!");
	}
	img.src = "http://www.baidu.com";

 

2.JSONP

JSONP是JSON with padding(填充式JSON或参数式JSON)的简写,是应用JSON的一种新方法。JSONP看起来与JSON差不多,只不过是被包含在函数调用中的JSON,如:
	callback({"name":"zhangsan"});
由两部分组成:1.回调函数,当响应到来时应该在页面中调用的函数,一般在请求中指定回调函数的名字。
2.数据,传入回调函数中的JSON数据。
 
	function handleResponse(response){
		console.log(response);
	}
	var script = document.createElement("script");
	script.src = "http://localhost:8080/wgps/tmsweb/queryFreightOrderByPage.action?callback=handleResponse";
	document.body.insertBefore(script,document.body.firstChild);
 
相关TAG标签
上一篇:win7激活工具下载 | 小马win7激活工具
下一篇:PhantomJS(webkit)/SlimerJS(Gecko)+CasperJS获取JavaScript渲染后的网页内容
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站