一、介绍
Ajax是一种能够向服务器请求额外的数据而无需写在页面的技术,它能带来更好的用户体验,改变了以往“单击,等待”的交互模式,可以实现无刷新加载页面。
【注】其实ajax可以运行在非服务器环境,但是因为某些原因,ajax请求的文件,必须在服务器环境,所以导致ajax也要在服务器环境
1.1 优缺点
优点
- 无刷新加载页面
- 提升了用户体验
- 提升了页面的渲染速度
缺点
- 不会产生前进后退和历史记录
- 搜索引擎,检索不到,由js引起的数据变化,破坏了SEO
1.2 XHR
Ajax技术的核心是XMLHttpRequest对象(简称XHR),XHR为向服务器发送请求和解析服务器响应提供了流畅的接口(也就是用来连接前后端,承载交互的数据)。能够以异步方式从服务器取得跟多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。也就是说,可以使用XHR对象取得新数据,然后再通过DOM将新数据插入到页面中。
1.2.1 属性
-
responseText:作为相应主体被返回的文本
-
responseXML:如果相应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着详情数据的XML DOM文档
-
status:相应的HTTP状态
- 1**:请求收到,继续处理
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本 - 2**:操作成功收到,分析、接受
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求 - 3**:完成此请求必须进一步处理
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除 - 4**:请求包含一个错误语法或不能完成
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求 - 5**:服务器执行一个完全有效请求失败
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本
- 1**:请求收到,继续处理
-
statusText:HTTP状态的说明
-
readyState:请求/相应过程的当前活动阶段
- 0:未初始化。尚未调用open()方法
- 1:启动(载入)。已经调用open()方法,但尚未调用send()方法
- 2:发送(载入完成)。已经调用send()方法,但尚未接受到响应
- 3:接收(交互)。已经接收到部分响应数据
- 4:完成(完成)。已经接收到全部响应数据,而且已经可以在客户端使用了
只要redayState属性的值由一个值编程另一个值,都会触发一次readystatechange事件。可以利用这个事件来检测每次状态变化后readyState的值。通常,我们只去关心readyState值为4的阶段,因为这时候所有出具都已经就绪。
1.2.2 方法
open()
- 要发送的请求的类型:get或post
- GET是最常见的请求类型,最常用于像服务器查询某些信息。必要时,可以将查询字符串参数追加到URL的末尾,以便将信息发送给服务器
- POST是频率仅次于GET的POST请求,通常用于向服务器发送应该被保存的数据。post请求应该把数据作为请求的主体提交,而GET请求传统上不是这样。POST请求的主体可以包含非常多的数据,而且格式不限。
- 【注】POST请求消耗的资源比GET更多一些,从性能角度上看,以发送相同的数据计,GET请求的速度最多可达到POST请求的两倍。
- 请求的URL:
- 是否异步发送请求的布尔值
var ajax = newXMLHttpRequest();
ajax.open("get","example.php",true);
比如说这两行代码是发起了一个对example.php的GET请求,调用open()方法并不会真正发送请求。而只是启动一个请求以备发送。
【注】只能向同一个域中使用相同端口和协议的URL发送请求。如果URL与启动请求的页面有所差别,都会引发安全错误。
send()
要发送特定的请求,必须像下面这样调用send()方法
var ajax = newXMLHttpRequest();
ajax.open("get","example.php",true);
ajax.send(null);
这里的send()方法接收一个参数,即要作为请求主体发送的数据,如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必需的。调用send()方法后,请求就会被分派到服务器。
setRequestHeader()
该方法可以设置自定义的请求头部信息,这个方法接收两个参数:头部字段的名称和头部字段的值。要成功发送请求头部信息,必须在调用open()方法之后且调用send()方法之前调用setRequestHeader()方法
- 发送json格式数据
xhr.setRequestHeader(“Content-type”,“application/json; charset=utf-8”); - 发送表单数据
xhr.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded; charset=utf-8”); - 发送纯文本(不指定Content-type时,此是默认值)
xhr.setRequestHeader(“Content-type”, “text/plain; charset=utf-8”); - 发送html文本
xhr.setRequestHeader(“Content-type”, “text/html; charset=utf-8”); - 编码可带可不带
// 不带字符编码写法 xhr.setRequestHeader(“Content-type”, “application/json”); - 值对大小写不敏感(但是尽量小写)
xhr.setRequestHeader(“Content-type”,“Application/JSON; charset=utf-8”);
二、封装
2.1 ajaxGet
function ajaxGet(url,data){
data = data || {};
var str = '';
for(var i in data){
str = str + i + "=" + data[i] + "&";
}
var d = new Date();
url = url + "?" + str + "__qft="+d.getTime();
var p = new Promise(function(success,error){
var ajax = new XMLHttpRequest();
ajax.open("get",url,true);
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
success(ajax.responseText);
}else if(ajax.readyState == 4 && ajax.status != 200){
error(ajax.status);
}
}
ajax.send();
})
return p;
}
2.2 ajaxPost
function ajaxPost(url,data){
data = data || {};
var str = "";
for(var i in data){
str += `${i}=${data[i]}&`;
}
str = str.slice(0,str.length-1);
var p = new Promise(function(success,error){
var ajax = new XMLHttpRequest();
ajax.open("post",url,true);
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200){
success(ajax.responseText)
}else if(ajax.readyState == 4 && ajax.status != 200){
error(ajax.status)
}
}
ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
ajax.send(str);
})
return p;
}
2.3 jsonp
将jsonp放在这是因为它的封装和上述封装相似,而且它能利用script标签加载外部文件不受同源策略限制的特性解决跨域问题
function jsonp(url,data){
data = data || {};
var str = "";
for(var i in data){
str += `${i}=${data[i]}&`;
}
var d = new Date();
url = url + "?" + str + "__qft=" + d.getTime();
var p = new Promise(function(success){
var script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
window[data[data.columnName]] = function(res){
success(res)
}
})
return p;
}