我们在学习一个东西的时候首先要知道,学习的东西是什么,他可以干什么,为什么使用它?
那么到底什么是ajax呢?
AJAX 不是 JavaScript 的规范,他是一个老伙计自创的名字 : Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求。
他可以干什么呢?
在整个网页不重新加载的情况下,更新部分页面的内容。
为什么要使用它呢?
根据业务需求,发送http请求,拿到服务端数据,在页面上渲染数据。
好,言归正传,让我们开始学习AJAX
什么是xhr
ajax技术的核心就在于 XMLHttpRequest
对象(简称xhr),首先由微软引用,随后,其他浏览器也支持啦该对象, xhr为向服务器发送请求和解析服务器响应提供啦流畅的接口。
IE5中xhr对象,是通过ActiveX对象实现的,IE7+即其他浏览器都支持xhr对象,所以需要写一个兼容
// 创建一个xhr对象(带兼容处理)
function create(){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
return xhr;
}
注意,如果需要多个请求,就创建多个xhr对象,当然也可以使用同一个xhr对象,但是这回终止xhr对象之前的异步请求
xhr对象的方法
open()
在使用xhr对象,第一个要调的方法是open(method,ull,async)
该方法是向服务器发送之前做一些设置,比如你打电话,输入电话号,然后看看是用卡一还是卡二,
xhr.open('GET','http://www.example.com/api',true)
/*
第一个参数表示使用哪种http请求方法,不区分大小写,一般还是写大写的,常用的两个方法:get()、post()
get方法用于常规请求,一般从服务器读取数据使用该方法
post方法常用语HTML表单请求,一般向服务器发送数据使用该方法
第二个参数表示url,要请求的资源地址
第三个参数表示是否异步,true\false
/*
send()
send方法接受一个参数,即要作为请求主体发送的数据,调用send的方法,请求发送到服务器,该方法等于按下拨打按钮
如果是GET方法,send()无参数或为null;如果是POST方法参数是要发送的数据
xhr.send('a=1&b=2');
xhr对象的事件
xhr.onerror
xhr.onerror = function(e){
console.log(e)
}
// 该事件当请求失败时触发
xhr.ontimeout
xhr.timeout = 1000; // 设置请求时间的限制,毫秒为单位,默认为0,
xhr.ontimeout = function(){
alert('请求超时')
}
// 当请求超过指定的时间时触发
xhr.onprogress
// 监听进度事件,如果请求的资源很小,直接就100%
xhr.onprogress = function(e){
console.log((e.loaded / e.total) * 100 + '%');
}
接收响应
先检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段。这个属性可取的值如下:
0(UNSENT):未初始化。尚未调用open()方法
1(OPENED):启动。已经调用open()方法,但尚未调用send()方法
2(HEADERS_RECEIVED):发送。己经调用send()方法,且接收到头信息
3(LOADING):接收。已经接收到部分响应主体信息
4(DONE):完成。已经接收到全部响应数据,而且已经可以在客户端使用了
在XHR对象的 readyState
属性改变的话会触发XHR对象的 onreadystatechange
事件,所以我们通常使用onreadystatechange事件监听状态的变化
注意:一定要在open之前设置 onreadystatechange
事件,才能确保跨浏览器兼容性,否则将无法接收readyState属性为0和1的情况
xhr.onreadystatecahnge = function (){
if(xhr.readyState){
// another code
}
}
单单上边的处理还是不够的,因为xhr.readyState是指运行ajax所经历的几种状态,所以还需要判断ajax是否请求成功
一个完整的HTTP响应由状态码、响应头集合和响应主体组成。在收到响应后,这些都可以通过XHR对象的属性和方法使用,主要有以下4个属性
responseText: 作为响应主体被返回的文本(文本形式)
responseXML: 如果响应的内容类型是'text/xml'或'application/xml',这个属性中将保存着响应数据的XML DOM文档(document形式)
status: HTTP状态码(数字形式)
statusText: HTTP状态说明(文本形式)
xhr.onreadystatechange = function(){
if(xhr.readyState){
if(xhr.status>= 200 && xhr.status < 300 || xhr.status == 304){
}
}
}
关于xhr.status的解释 : https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/5053660?fr=aladdin
最后上一篇我自己封装的ajax吧
const ajax = (json) => {
let xhr = null,
type = json.type.toUpperCase() || 'GET'; // 设置请求的默认方法
// 兼容处理
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
// 设置请求时间的限制
xhr.timeout = json.time ? json.time : 0;
// 设置请求找过指定时间的时间
xhr.ontimeout = json.timeout ? json.timeout : null;
// 监听xhr对象额状态
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
json.success(xhr.responseText) // 如果成功 即调用成功的回调函数
}else{
json.error&&json.error() // 失败调用失败的回调函数
}
}
}
if(type.toUpperCase() == 'GET'){
xhr.open('GET',json.url+'?'+toStr(json.data),true);
xhr.send()
}else if(type.toUpperCase() == 'POST'){
xhr.open('POST',json.url,true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(toStr(json.data))
}
}
// 将对象的属性和value转换为 a:1&b:2
const toStr = json => {
var arr = [];
for(var i in json){
arr.push(i+'='+json[i])
}
return arr.join('&')
}