js系列教程11-json、ajax(XMLHttpRequest)、comet、SSE、WebSocket全解

全栈工程师开发手册 (作者:栾鹏)

快捷链接:
js系列教程1-数组操作全解
js系列教程2-对象和属性全解
js系列教程3-字符串和正则全解
js系列教程4-函数与参数全解
js系列教程5-容器和算法全解
js系列教程6-BOM操作全解
js系列教程7-DOM操作全解
js系列教程8-事件全解
js系列教程9-表单元素全解
js系列教程10-canvas绘图全解
js系列教程11-json、ajax、comet全解
js系列教程12-离线应用与存储全解
js系列教程13-原型、原型链、作用链、闭包全解

js中json 全解

js对象

var person0={
	name:"person0",                         //key和value间用冒号连接
	age:11                                  //不同的key-value对之间用逗号连接,最后一个value后不加符号。
};    	

json对象

var person0 = {
	"name":"person0",                       //与js对象的对象字面量的区别在于属性必须加引号
	"age":12 
};  
var person1 = {
	"name":"person1",
	"age":12,
	"school":{                              //JSON中对象可以嵌套。每个JSON对象使用{}包含
		"name":"school1", 
		"address":"北大对面" 
	} 
	toJSON:function(){                      //toJSON函数是对象序列化时的调用虚函数
		return this.name;
	} 
};  

json数组

var persons = [person0,person1,person2];     //JSON数组,每一个元素都是json对象

json对象的操作

person0.name = "person0"   				//json对象与js对象操作方法相同
person0['name'] = 'person0'
person0.newName = "pppp"  				//也是支持属性的增删查改操作

json数组元素的操作

persons[2].age=person0.age;                                   //JSON中数组对象与js对象使用方法相同

将js对象、json对象、json数组转化json字符串(序列化)

var personstr = JSON.stringify(persons);                     //JSON.stringify将对象(js的或JSON的)转化为JSON字符串(称为序列化)。可以序列化对象或对象数组。会自动滤出值为underfined的属性。

person2str =JSON.stringify(person2,["name","age"],"--");    //第二个参数是过滤器,表示只保留name和age两个属性。第三个参数是换行缩进,可为数字缩进空格数目,最大缩进为10,可为字符串,表示缩进字符串。调用stringify,执行顺序:toJSON虚函数或对象本身->函数过滤器->存在属性进行序列化->缩进参数进行格式化

personstr = JSON.stringify(person2,function(key,value){        //使用函数为过滤器
   if(key=="name"||key=="age")
        return value;
    else
        return undefined;                                       //返回undefined就不会再被序列化
},4);                                                          

将json字符串转化为json对象、json数组

persons = JSON.parse(personstr);                             //JSON.parse将字符串转化为js对象或数组

person2 = JSON.parse(person2str,function(key,value){            //使用函数控制转化操作
  if(key=="name") return "family"+value;
    else return value;
});

js中的ajax(XMLHttpRequest)

Ajax的核心是XmlHttpRequest。我们通过对该对象的操作来进行异步的数据请求。

实际上我们接触到最多的应该是jQuey对ajax的封装,比如 . a j a x , .ajax, .ajax.post等,如果用Angular的话我们可以用$http服务。

除了这些之外,我们可以使用第三方的Ajax库qwest等。

jquery中ajax的使用可以参考jquery系列教程6-ajax的应用全解

这里作为js的系列文章,我们只介绍js中的XmlHttpRequest。

创建请求对象

var xhr = new XMLHttpRequest();                                 //创建XHR对象

状态变化函数

xhr.onreadystatechange=function(){                              //onreadystatechange状态变化函数
    console.log("readstate="+xhr.readyState.toString());             //readyState的取值0为未初始化,未调用open,1已open未send,2已send未回复,3回复部分,4全部回复
    if(xhr.readyState==3)                                       //在后台使用推送机制的话,前端会间断的收到推送数据,状态为3。
        console.log(xhr.responseText);                               //responseText包含曾经的所有推送数据,所以每次读取应该根据旧数据长度查找最新的数据的位置。这里省略了
};

响应完成事件

xhr.onload=function(){    								//无论什么响应,接收完成就触发
	console.log("接收响应完成");
	};  

响应异常事件

xhr.onerror=function(){
	console.log("响应出错");
};      

进度事件

xhr.onprogress=function(event){                                  
    if(event.lengthComputable){                                     //lengthComputable表示进度信息是否可用
        console.log("进度"+event.position*1.0/event.totalSize);        //position表示已接收数,totalSize表示预期接收数
    }
};

请求初始化

xhr.open("get","example.php?qunid=12",false);                   //opet准备启动请求,参数:请求类型post或get,请求地址,是否异步发送。同步的话会等待程序返回方可继续

自定义头部信息

xhr.setRequestHeader("myheader","myvalue");                       //发送自定义信息

发送请求

xhr.send(null);                                                     //发送请求,如果是同步,会直到响应完毕才会继续运行。参数:请求主体。xhr.abort()取消异步请求

获取响应

if((xhr.status>200 && xhr.status<300)|| xhr.status==304)
{
    console.log(xhr.responseText);                                       //responseText返回数据,responseXML在响应类型为text/xml和application/xml时返回XML的响应数据
    console.log(xhr.getResponseHeader("myback"));                        //读取服务器返回在自定义头部信息
    console.log(xhr.getAllResponseHeaders());                             //返回所有信息
}
else 
	console.log("失败:"+xhr.status);                                  //statusText表示HTTP状态描述,各浏览器不同

超时函数

xhr.ontimeout = function(){
	console.log("响应超时")
};

请求数据序列化

var data = new FormData(myform);                   //序列化表单,也可以通过new FormData(),创建空的对象
data.append("qunid","21");                         //添加键值对
data.append("file1",files[0]);                     //可以在包含file的表单中直接添加文件


xhr.open("post","example.php",true);
xhr.send(data);                                    //发送序列化数据

comet:基于http长连接的“服务器推”技术

Ajax的出现使客户端与服务器端传输数据少了很多,也快了很多,也满足了以丰富用户体验为特点的web2.0时代 初期发展的需要,但是慢慢地也暴露了他的弊端。比如无法满足即时通信等富交互式应用的实时更新数据的要求。这种浏览器端的小技术毕竟还是基于http协议,http协议要求的请求/响应的模式也是无法改变的,除非http协议本身有所改变。

对于某些特定的业务需求,比如通知,我们需要有及时的数据更新,我们能够想到的就是使用setInterval每隔一定时间比如10s去获取一次请求,从而做到一些通知更新,但是这并不一种高效的做法,这会增加服务器的请求数量。

这个时候有了另外一种概念,“反向Ajax”,由服务器进行数据推送, Comet能够让信息近乎实时的被推送到页面上,非常适合要求实时性的获取的数据的页面。客户端与服务器端保持一个长连接,只有客户端需要的数据更新时,服务器才主动将数据推送给客户端。

Comet的实现主要有两种方式,基于Ajax的长轮询(long-polling)方式和基于 Iframe 及 htmlfile 的流(http streaming)方式。

因此可以说comet主要是在服务器端由后台来进行完成。

前端要做的就是通过ajax请求成功后,在XMLHttpRequest的onreadystatechange函数中持续获取数据。

var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function() {                          //服务器实现comet技术,当后台发来数据后,会自动触发这个函数。连接不关闭
	 console.log(xhr.readyState);
	 if (xhr.readyState === 3 && xhr.status === 200) {
	  //获取成功后执行操作
	  //数据在xhr.responseText
	  console.log(xhr.responseText);
 }
};

SSE

SSE(Server-Sent Event,服务端推送事件)是一种允许服务端向客户端推送新数据的HTML5技术。与由客户端每隔几秒从服务端轮询拉取新数据相比,这是一种更优的解决方案。

var source = new EventSource("myevent.php");         //参数:入口点。必须与创建对象的页面同源(url模式,域、端口)。连接断开会自动建立,或者使用source.close()强制断开
source.onmessage = function(event){                  //open在连接建立时触发,message在接收到新数据时触发,error在无法建立连接时触发
    console.log(event.data);                         //推送数据保存在event.data中
};
source.onerror=function(){
	console.log("连接失败");
	console.log("连接状态"+source.readyState)         //readyState属性0表示正在连接,1表示打开了链接,2表示关闭了链接
};  

WebSocket

在新一代html标准html5中提供了一种浏览器和服务器间进行全双工通讯的网络技术Websocket。从Websocket草案得知,Websocket是一个全新的、独立的协议,基于TCP协议,与http协议兼容、却不会融入http协议,仅仅作为html5的一部分。

HTML5 WebSocket 设计出来的目的就是要取代轮询和 Comet 技术,使客户端浏览器具备像 C/S 架构下桌面系统的实时通讯能力。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

也就是我们可以使用web技术构建实时性的程序比如聊天游戏等应用。

意:SSE和 Web Sockets 都是新的api,需要专门服务器支持,需要大家考虑兼容性。


var socket = new WebSocket("ws://www.example.com/server.php");      //未加密的链接不使用http,而是ws,加密的使用wss
socket.send("hello world");                                         //发送数据
socket.onmessage=function(event){                                   //web socket有open、error、close事件
    console.log(event.data);
    console.log(socket.readyState);                                 //0表示正在建立,1已经建立,2正在关闭,3已经关闭
};

总结

AJAX – 请求 → 响应 (频繁使用)

Comet – 请求 → 挂起 → 响应 (模拟服务端推送)

Server-Sent Events – 客户单 ← 服务端 (服务端推送)  
  
  WebSockets – 客户端 ↔ 服务端 (未来趋势,双工通信)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾讯数据架构师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值