by caix in 深圳
Ajax是一种从页面向服务器请求数据的技术,Comet是一种服务器向页面推送数据的技术,能够让信息近乎实时的被推送到页面上。
实现 Comet方式:长轮询,流
主流的 Web端 即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(Server-sent Events)
Ajax
Ajax 是对Asynchronous JavaScript + XML的简写
Ajax 技术的核心是 XMLHttpRequest对象(简称 XHR)
XMLHttpRequest 对象
IE7+、Firefox、Opera、Chrome 和 Safari 都支持原生的 XHR 对象,在这些浏览器中创建 XHR 对象 要像下面这样使用 XMLHttpRequest 构造函数
定义
let xhr = new XMLHttpRequest()
完整版本
// 先检测原生 XHR 对象是否存在,如果存在则返回它的新实例
var createXHR = () => {
// 先检测原生 XHR 对象是否存在,如果存在则返回它的新实例
if (typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
// 如果原生对象不存在,则检测 ActiveX 对象
} else if (typeof ActiveXObject != "undefined"){
if (typeof arguments.callee.activeXString != "string"){
var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i, len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//跳过
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
}
使用方法
1、open()
xhr.open("get", "example.php", false);
要发送的请求的类型("get"、"post"等)、请求的 URL 和表示是否异步发送请求的布尔值用 open() 方法并不会真正发送请求,而只是启动一个请求以备发送。
2、send()
接收一个参数,即要作为请求主体发送的数据。
如果不需要通过请求主体发送数据,则必须传入 null,因为这个参数对有些浏览器来说是必需的。
在收到响应后,响应的数据会自动填充 XHR 对象的属性,相关的属性简介如下。
responseText:作为响应主体被返回的文本。
responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的 XML DOM 文档。
status:响应的 HTTP 状态。
同步请求
xhr.open("get", "example.txt", false);
xhr.send(null);
//状态代码为 304 表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本;当然,也意味着响应是有效的。
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
但多数情况下,我们还是要发送异步请求,才能让JavaScript 继续执行而不必等待响应。此时,可以检测 XHR 对象的 readyState 属性,该属性表示请求/响应过程的当前活动阶段。该属性可取:
0:未初始化。尚未调用 open()方法。
1:启动。已经调用 open()方法,但尚未调用 send()方法。
2:发送。已经调用 send()方法,但尚未接收到响应。
3:接收。已经接收到部分响应数据。
4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
只要 readyState 属性的值由一个值变成另一个值,都会触发一次readystatechange 事件。可以利用这个事件来检测每次状态变化后 readyState 的值
总体创建 ajax
// 一、创建Ajax实例
let xhr = new XMLHttpRequest(); //IE下为ActiveObject对象
//二、打开请求: 发送请求之前的一些配置项
//1.HTTP METHOD:GET/POST/PUT/DELETE/HEAD/OPTIONS/TRACE/CONNECT/
//2.url:接口地址
//3.async:设置Ajax的同步异步,默认是异步
//4.user-name/user-pass用户名和密码,一般不用
xhr.open(method, url, async, [user-name], [user-pass])
//三、事件监听:一般监听的都是readystatechange事件(Ajax状态改变事件),基于这个事件可以获取服务器返回的响应头响应主体
xhr.onreadystatechange = () => {
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
}
};
//四、发送Ajax请求:从这步开始,当前Ajax任务开始,如果Ajax是同步的,后续代码不会执行,要等到Ajax状态成功后再执行
xhr.send([请求主体内容])
3、xhr.abort();
接收到响应之前还可以调用 abort()方法来取消异步请求
XMLHttpRequest 2 级
XMLHttpRequest 1级 只是把已有的 XHR 对象的实现细节描述了出来
XMLHttpRequest 2级 则进一步发展了 XHR
1、FormData
现代 Web 应用中频繁使用的一项功能就是表单数据的序列化,XMLHttpRequest 2 级为此定义了 FormData 类型
var xhr = createXHR();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("post","postexample.php", true);
// 添加FormData数据
var form = document.getElementById("user-info");
xhr.send(new FormData(form));
使用 FormData 的方便之处体现在不必明确地在 XHR 对象上设置请求头部。XHR 对象能够识别传入的数据类型是 FormData 的实例,并配置适当的头部信息。
支持 FormData 的浏览器有 Firefox 4+、Safari 5+、Chrome 和 Android 3+版 WebKit
2、超时设定
IE8 为 XHR 对象添加了一个 timeout 属性,表示请求在等待响应多少毫秒之后就终止
var xhr = createXHR();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
try {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
} catch (ex){
//假设由 ontimeout 事件处理程序处理
}
}
};
xhr.open("get", "timeout.php", true);
xhr.timeout = 1000; //将超时设置为 1 秒钟(仅适用于 IE8+)
xhr.ontimeout = function(){
alert("Request did not return in a second.");
};
xhr.send(null);
3、进度事件
Progress Events 规范是 W3C 的一个工作草案,定义了与客户端服务器通信有关的事件。这些事件最 早其实只针对 XHR 操作,但目前也被其他 API 借鉴。有以下 6 个进度事件
oadstart:在接收到响应数据的第一个字节时触发。
progress:在接收响应期间持续不断地触发。
error:在请求发生错误时触发。
abort:在因为调用 abort()方法而终止连接时触发。
load:在接收到完整的响应数据时触发。
loadend:在通信完成或者触发 error、abort 或 load 事件后触发。
4、progress事件
对 XHR 的另一个革新是添加了progress\color{#0000FF}{progress}progress事件,这个事件会在浏览器接收新数据期间周期性地触发。而onprogress\color{#0000FF}{onprogress}onprogress事件处理程序会接收到一个event\color{#0000FF}{event}event对象,其 target 属性是 XHR 对象,但包含着三个额外的属性:lengthComputable、position 和 totalSize。
engthComputable是一个表示进度信息是否可用的布尔值,
position 表示已经接收的字节数
totalSize 表示根据
Content-Length 响应头部确定的预期字节数。
var xhr = createXHR();
xhr.onload = function(event){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
};
// open 之前调用,每次触发都会以新的状态信息更新 HTML 元素的内容
//如果响应头部中包含Content-Length 字段,那么也可以利用此信息来计算从响应中已经接收到的数据的百分比。
xhr.onprogress = function(event){
var divStatus = document.getElementById("status");
if (event.lengthComputable){
divStatus.innerHTML = "Received " + event.position + " of " +
event.totalSize +" bytes";
}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);
在这里我们一定想到了最常写的图片上传并显示进度百分比的业务,就是通过监听progress
跨资源共享
1.CORS
我们都知道ajax是同源策略,协议、域名、端口一致。 CORS(Cross-Origin Resource Sharing,跨源资源共享是 W3C 的一个工作草案,定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通
CORS 背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败
var xhr = createXHR();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "http://www.somewhere-else.com/page/", true);
xhr.send(null);
2、带凭据请求
默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端 SSL 证明 等 )。 通 过 将 withCredentials属性设置为 true,可以指定某个请求应该发送凭据。如果服务器接受带凭据的请 求,会用下面的 HTTP 头部来响应
Access-Control-Allow-Credentials: true
其他跨域技术
1. 图像ping
原理:利用标签的src属性,图像 Ping 是与服务器进行简单、单向的跨域通信的一种方式。
请求的数据是通过查询字符串形式发送的,而响应可以是任意内容,但通常是像素图或 204 响应。
缺点:
1.只能发送 GET 请求
2.无法访问服务器的响应文本。
因此,图像 Ping 只能用于浏览器与服务器间的单向通信。
2. JSONP
JSONP是JSON withpadding(填充式 JSON 或参数式 JSON)的简写,是应用 JSON 的一种新方法,
JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的JSON数据。
原理:通过<script>标签里不受限制地从其他域加载资源
3. Comet
指的是一种更高级的 Ajax 技术,Ajax 是一种从页面向服务器请求数据的技术,而 Comet 则是一种服务器向页面推送数据的技术。Comet 能够让信息近乎实时地被推送到页面上,非常适合处理体育比赛的分数和股票报价
有两种实现 Comet 的方式:长轮询和流。长轮询是传统轮询(也称为短轮询)的一个翻版,即浏览器定时向服务器发送请求,看有没有更新的数据。
两者最大的区别:
在于服务器如何发送数据
短轮询是服务器立即发送响应,无论数据是否有效,
长轮询是等待发送响应。
轮询的优势是所有浏览器都支持,因为使用 XHR 对象和 setTimeout()就能实现。而你要做的就是决定什么时候发送请求
所有浏览器都支持长轮询,而只有部分浏览器原生支持 HTTP 流
4、其他
SSE(Server-Sent Events,服务器发送事件)是一种实现 Comet 交互的浏览器 API,既支持长轮询,也支持 HTTP 流。SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据
Web Sockets 是一种与服务器进行全双工、双向通信的信道。与其他方案不同,Web Sockets 不使用 HTTP 协议,而使用一种自定义的协议。这种协议专门为快速传输小数据设计。虽然要求使用不同的 Web 服务器,但却具有速度上的优势
标签:status,请求,xhr,XHR,响应,Ajax,Comet,第二十
From: https://www.cnblogs.com/caix-1987/p/17291222.html