ajax的出现
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新,提升了用户体验。
如何发起一个ajax请求
XMLHttpRequest 对象是ajax的基础,目前所有浏览器都支持XMLHttpRequest(IE兼容的本文不做介绍)
4步:
1、创建XMLHTTPRequest对象
2、注册事件,监听和服务器交互进度。在调用open之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性
3、使用open方法设置和服务器的交互信息
4、设置发送的数据,开始和服务器端交互
PS:默认情况下,JavaScript在发送AJAX请求时,URL必须和当前页面同域,由于浏览器同源策略的限制。
下面给大家列出get请求和post请求的例子
get请求:
可能得到的是缓存结果,可在url后面跟上时间戳以获取最新的结果。查询字符串中的每个参数名和值都必须使用encodeURIComponent进行编码,然后在放到URL的末尾,而且所有名-值对都必须由&分隔。
var ajax = new XMLHttpRequest();//步骤一:创建异步对象
ajax.onreadystatechange = function () {//步骤二:注册事件 onreadystatechange 状态改变就会调用
if (ajax.readyState==4 &&ajax.status==200) {
//如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
console.log(ajax.responseText);//输入相应的内容
}
}
ajax.open('get','getStar.php?starName='+name);//步骤三:设置请求的url参数
ajax.send();//步骤四:发送请求
post请求:
请求头设置在open和send之间
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () {
// 这步为判断服务器是否正确响应
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.open('post', '02.post.php' );
//如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send('name=fox&age=18');
请求的响应过程
检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段,属性值0,1,2,3,4介绍:
- 0:未初始化,未调用open方法。
- 1:启动,已经调用open方法,未调用send方法
- 2:发送,调用send方法,未接收到响应。
- 3:接收,已经接收到部分响应数据
- 4:完成
只要readyState属性的值由一个值变成另一个值,都会触发一次readystatechange事件,可以利用这个事件来检测每次状态变化后的readyState的值,通常我们只对readyState值为4的阶段感兴趣。
响应的处理
在收到响应后,响应的数据会自动填充XHR对象的属性,相关的属性如下:
- responseText:作为响应主体返回的文本。
- responseXML:如果响应的内容类型是”text/xml”或”application/xml”,这个属性中将保存包含着响应数据的XML DOM文档。
- status:响应的HTTP状态。
- statusText:HTTP状态的说明。
http状态码的处理
在接收到响应后,第一步是检查status属性,以确定响应已经成功返回,为确保接收到适当的相应,应该像下面这样写:
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”,”sxample”,true); xhr.send(null);
http状态码表,要更详细的信息戳链接http状态码详解
304说明:文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。所以这个也相当于请求成功
响应内容的处理
属性
响应头的处理
getAllResponseHeaders方法和getResponseHeader方法
XMLHttpRequest 对象详解
方法
open方法
open(method,url,async),参数分别为:请求方式,请求地址,同步还是异步请求(async表示同步还是异步,默认为true(异步))
send方法
send(string) :string仅用于 POST 请求,把请求的body部分以字符串或者FormData
对象传进去。
abort方法
在接收到响应(readyState=4)之前还可以调用abort()方法来取消异步请求,调用这个方法后,XHR对象会停止触发事件,而且也不再允许访问任何与响应有关的对象属性,在终止请求之后,还应该对XHR对象进行解引用操作,不建议重用XHR对象。
这个方法把 XMLHttpRequest 对象重置为 readyState 为 0 的状态,并且取消所有未决的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。
getAllResponseHeaders方法
把 HTTP 响应头部作为未解析的字符串返回。
如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 " " 隔开
- HTTP头部信息
每个HTTP请求和响应都会带有相应的头部信息,头部信息有:
- Accept:浏览器能够处理的内容类型。
- Accept-Charset:浏览器能够现实的字符集。
- Accept-Encoding:浏览器能处理的压缩编码。
- Accept-Language:浏览器当前设置的语言。
- Connection:浏览器与服务器之间的连接类型。
- Cookie:当前页面设置的任何Cookie。
- Host:发出请求的页面所在的域
- Referer:发出请求的页面的URL。
- User-Agent:浏览器的用户带来字符串。
getResponseHeader方法
返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。
该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyState 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并返回,使用逗号和空格分隔开各个头部的值。
属性
responseText
目前为止为服务器接收到的响应体(不包括头部),或者如果还没有接收到数据的话,就是空字符串。
如果 readyState 小于 3,这个属性就是一个空字符串。当 readyState 为 3,这个属性返回目前已经接收的响应部分。如果 readyState 为 4,这个属性保存了完整的响应体。
如果响应包含了为响应体指定字符编码的头部,就使用该编码。否则,假定使用 Unicode UTF-8。
responseXML
如果响应的MIME类型是”text/xml”或”application/xml”,这个属性中将保存包含着响应数据的XML DOM文档(解析为 XML 并作为 Document 对象返回)。
statusText
这个属性用名称而不是数字指定了请求的 HTTP 的状态代码。也就是说,当状态为 200 的时候它是 "OK",当状态为 404 的时候它是 "Not Found"。和 status 属性一样,当 readyState 小于 3 的时候读取这一属性会导致一个异常。
事件
load事件
响应接收完毕后将触发load事件,因此也就没有必要去检查readystate属性了,而onload事件处理程序会接收到一个event对象,其target属性就指向xht对象实例。但并非所有浏览器都为这个事件实现了适当的事件对象。
var xhr=createXHR(); xhr.onload=function(){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“request was unsuccessful:”+xhr.status); } }; xhr.open(“get”,”alrevents.php”,true); xhr.send(null);
progress事件
这个事件会在浏览器接收新数据期间周期性的触发,而onprogress事件处理程序会接收一个event对象,其target属性是XHR对象,但包含着三个额外的属性:lengthComputable、position和totalSize。
LengthComputable是一个表示进度信息是否可用的布尔值
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 wa unsuccessful:”+xhr.status); } }; xhr.onprogress-function(event){ var divStatus=document.getElementById(“status”); if(event.lengthComputable){ if(event.lengthComputable){ divStatus.innerHTML=”Received ”+event.position+” of ”+event.totalSize+”bytes”; } } }; xhr.open(“get”,”altevents.php”,true); xhr.send(null);
哪些处理要放在open和send之间
请求超时设定
表示请求在等待响应多少毫秒之后就终止,在给定的时间内浏览器还没有接收到响应,那么就会触发timeout事件,进而会调用ontimeout事件出来程序
xhr.open(“get”,”timeout.php”,true); xhr.timeout=1000; xhr.ontimeout=function(){ alert(“Request did not return in a second”); }; xhr.send(null);
重写XHR响应的MIME类型
overrideMineType方法用于重写XHR响应的MIME类型,因为返回响应的MIME类型决定了XHR对象如何处理它(是指把数据填充在哪个属性?),所以提供一种方法能够重写服务器返回的MIME类型是很有用的。
xhr.open(“get”,”text.php”,true); xhr.overrideMineType(“text/xml”); xhr.send(null);
Ajax优缺点
Ajax的优点
1.无刷新更新数据。
AJAX最大优点就是能在不刷新整个页面的前提下与服务器通信维护数据。这使得Web应用程序更为迅捷地响应用户交互,并避免了在网络上发送那些没有改变的信息,减少用户等待时间,带来非常好的用户体验。
2.异步与服务器通信。
AJAX使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。优化了Browser和Server之间的沟通,减少不必要的数据传输、时间及降低网络上数据流量。
3.前端和后端负载平衡。
AJAX可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,AJAX的原则是“按需取数据”,可以最大程度的减少冗余请求和响应对服务器造成的负担,提升站点性能。
4.基于标准被广泛支持。
AJAX基于标准化的并被广泛支持的技术,不需要下载浏览器插件或者小程序,但需要客户允许JavaScript在浏览器上执行。随着Ajax的成熟,一些简化Ajax使用方法的程序库也相继问世。同样,也出现了另一种辅助程序设计的技术,为那些不支持JavaScript的用户提供替代功能。
5.界面与应用分离。
Ajax使WEB中的界面与应用分离(也可以说是数据与呈现分离),有利于分工合作、减少非技术人员对页面的修改造成的WEB应用程序错误、提高效率、也更加适用于现在的发布系统。
Ajax缺点
1.AjAX干掉了Back和加入收藏书签功能,即对浏览器机制的破坏。
2.AJAX的安全问题。
AJAX技术给用户带来很好的用户体验的同时也对IT企业带来了新的安全威胁,Ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比以前更多的数据和服务器逻辑。Ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有Ajax也难以避免一些已知的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于Credentials的安全漏洞等等。
3.因为网络延迟需要给用户提供必要提示
进行Ajax开发时,网络延迟——即用户发出请求到服务器发出响应之间的间隔——需要慎重考虑。如果不给予用户明确的回应,没有恰当的预读数据,或者对XMLHttpRequest的不恰当处理,都会使用户感到厌烦。通常的解决方案是,使用一个可视化的组件来告诉用户系统正在进行后台操作并且正在读取数据和内容。
基础请求代码封装
function ajax_method(url,data,method,success) { // 异步对象 var ajax = new XMLHttpRequest(); // get 跟post 需要分别写不同的代码 if (method=='get') { // get请求 if (data) { // 如果有值 url+='?'; url+=data; }else{ } // 设置 方法 以及 url ajax.open(method,url); // send即可 ajax.send(); }else{ // post请求 // post请求 url 是不需要改变 ajax.open(method,url); // 需要设置请求报文 ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 判断data send发送数据 if (data) { // 如果有值 从send发送 ajax.send(data); }else{ // 木有值 直接发送即可 ajax.send(); } } // 注册事件 ajax.onreadystatechange = function () { // 在事件中 获取数据 并修改界面显示 if (ajax.readyState==4&&ajax.status==200) { // console.log(ajax.responseText); // 将 数据 让 外面可以使用 // return ajax.responseText; // 当 onreadystatechange 调用时 说明 数据回来了 // ajax.responseText; // 如果说 外面可以传入一个 function 作为参数 success success(ajax.responseText); } } }
ajax连接池
在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆 盖掉,如果每次都创建一个新的XMLHttpRequest对象,也会造成浪费。解决的办法就是创建一个XMLHttpRequset的对象池,如果池里 有空闲的对象,则使用此对象,否则将创建一个新的对象。
可以查看我github的ajax.js文件连接池部分的实现
参考文章: