目录
- AJAX
- XHR
- 创建AJAX请求
- GET和POST传递参数
- XHR的state
- 其他事件监听
- 响应数据和响应类型
- http的状态码
- 超时时间
- 封装自己AJAX函数
 
- Axios
- 创建Axios请求实例
- 请求和响应拦截器
 
- Fetch
- Fetch与XHR的区别
- Fetch数据的响应
- 发送Fetch请求
 
 
- 封装Axios
AJAX
AJAX即异步的JavaScript 和 XML(Asynchronous JavaScript And XML)
 在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式,就是AJAX
 AJAX本身不是一种新技术,而是将现有技术结合起来的方法
 具体来说,实现AJAX有两种方式
XHR
第一种则是通过XHR
 XHR即XMLHTTPRequest,这是一个用于网络请求的对象,我们可以用它来发送和接收JSON,XML,HTML和TEXT等类型的数据
创建AJAX请求
创建一个AJAX请求通常分为四步
- 创建XMLHTTPRequestconst XHR = new XMLHttpRequest()
- 监听onreadystatechange事件,这个事件将会在网络请求状态每次改变后执行XHR.onreadystatechange = function() {console.log("状态发生了改变"); }
- 通过open方法配置网络请求XHR.open("get","")open方法接收三个参数,第一个参数是请求类型,如get、post、delete等等,第二个参数为向其发送请求的URL,第三个参数为布尔类型的可选参数,表示是否为异步操作,默认为true
- 调用send方法发送请求XHR.send()
GET和POST传递参数
通过GET请求来传递数据只能通过query参数
XHR.open("get","http://localhost:8088/get?name=zhangsan&age=18")
XHR.send()
事实上GET请求并不适合传递数据,如果想要大量传递数据需要使用POST请求
- POST请求通过- 表单传递数据- const form = document.querySelector("form") const formData = new FormData(form) XHR.open("post","http://localhost:8088/post") XHR.send(formData)
- 通过设置请求头为application/x-www-form-urlencoded的方式XHR.open("post","http://localhost:8088/post") const data = "name=zhangsan&age=18" XHR.setRequestHeader("Content-type","application/x-www-form-urlencoded") XHR.send(data)
- 通过设置请求头为application/json的方式XHR.open("post","http://localhost:8088/post") const data = JSON.stringify({name:"zhangsan",age:18}) XHR.setRequestHeader("Content-type","application/json; charset=utf-8") XHR.send(data)
XHR的state
在一次网络请求中XHR的状态会发生很多次变化
 我们可以在onreadystatechange事件中通过XHR.readyState拿到每次状态变化的值
| 状态码 | 意义 | 
|---|---|
| 0 | 请求被创建,但未调用open方法 | 
| 1 | open方法被调用 | 
| 2 | send方法被调用,并且头部和状态已可取得 | 
| 3 | 下载中 | 
| 4 | 下载操作已完成 | 
其他事件监听
| 事件名 | 作用 | 
|---|---|
| loadstart | 请求开始 | 
| progress | 第一个响应数据包到达 | 
| abort | 调用了XHR.abort()取消了请求 | 
| error | 发生连接错误 | 
| load | 请求完成 | 
| timeout | 请求超时,前提是设置了timeout | 
| loadend | 在load、error、timeout、abort之后触发 | 
响应数据和响应类型
发送了请求过后我们可以通过response属性来获取返回的数据
const res = XHR.response
返回数据的类型则是由responseType来决定
XHR.responseType = "json"
如果responseType值为空则为默认值text
 responseText返回的是text数据
 responseXML返回的则是XML
 在早期的服务器中返回的数据多是text和XML,所以那时多用responseText和responseXML来获取结果
 现在服务器返回多为json数据
http的状态码
除了请求有状态码之外,响应也有对应的状态码
 我们可以通过status和statusText来获取
const status = XHR.response.status;
const statusText = XHR.response.statusText;
具体关于HTTP响应码相关的内容可以看我这篇文章
 前端网络基础
超时时间
为了避免过长的网络请求时间而服务器迟迟无法返回数据的情况,我们可以设置一个超时时间
 当达到设置的时间后如果还没能拿到数据则会自动取消这个请求
 默认值为0,表示没有设置超时时间
 timeout的单位为毫秒
XHR.timeout = 10*1000
封装自己AJAX函数
function AJAX({method,url,asy = true,timeout = 0,data = {},success,failure
}) {const xhr = new XMLHttpRequest();xhr.responseType = "json"xhr.timeout = timeoutxhr.onload = function () {if (xhr.status == 200) {success(xhr.response)} else {failure(xhr.status, xhr.statusText)}}if (method || url || success || failure) {throw new Error("未传入指定参数")return;} else if (method.toLowerCase() == "get") {let query = []for (const key in data) {query.push(`${key}=${data[key]}`)}url = url + "?" + query.join("&")xhr.open(method, url, asy)xhr.send()} else if (method.toLowerCase() == "post") {xhr.open(method, url, asy)xhr.setRequestHeader("Content-type", "application/json")xhr.send(JSON.stringify(data))} else {throw new Error("不支持这种方法")}return xhr;
}const xhr = AJAX({method: "get",url: "http://localhost:8088/get",data: {name: "zhangsan"},success: function (res) {console.log(res)},failure: function (status, statusText) {console.log(status, statusText)}
})
Axios
Axios是一个基于promise的网络请求库
 它不仅可以在浏览器里发送网络请求,还可以在node.js中发送请求
 它还支持Promise
 请求/响应拦截器等等
创建Axios请求实例
当我们从Axios中导入对象时使用的实例为默认实例
 有时候默认实例的配置并不是我们所需的
 所以我们可以创建一个新的实例并传入属于该实例的配置
const ajax = axios.create({baseURL:"http://localhost:8088"	
})
通过我们创建的这个实例来发送请求
ajax.get("/get",{params:{}
}).then(res=>{console.log(res)
})ajax.post("/post",{name:"zhangsan",age:19}
}).then(res=>{console.log(res)
})
请求和响应拦截器
Axios也可以设置拦截器,拦截每次请求和响应
 请求拦截
axios.interceptors.request.use(function (config) {console.log("请求成功拦截")return config;}, function (error) {console.log("请求失败拦截")return error;});
响应拦截
axios.interceptors.response.use(function (response) {console.log("响应成功拦截")return response;}, function (error) {console.log("响应失败拦截")return error;});
Fetch
Fetch是一种更加现代的网络请求方案
 它是早期XMLHTTPRequest的替代方案
 同样也是AJAX的另一种实现方式
Fetch与XHR的区别
和XHR不同的是
- Fetch返回值是一个- Promise
- Fetch不像- XHR一样所有- 操作都在一个对象上
- XHR在上传文件时可以监控进度,- Fetch不行
Fetch数据的响应
Fetch将数据的响应分成了两个阶段
 当服务器返回了数据时为第一个阶段
- 在这个阶段我们可以通过检查http响应头来判断请求是否成功
- 如果因为网络问题,url不正确等导致Fetch无法建立http请求,那么Promise就会reject
- 当http响应码为404,500等异常状态码时将不会导致error
- 我们可以通过response.status来获得http状态码
第二个阶段为我们通过其他方法获取数据
- response.text()
 以- 文本的形式返回
- response.json()
 以- json的形式返回
发送Fetch请求
发送get请求
async function getData() {const response = await fetch("http://localhost:8088/get")const data = await response.json()console.log(data)
}
发送post请求
const params = {name:"zhangsan",age:18
}
async function getData() {const response = await fetch("http://localhost:8088/get",{method:"post",headers:{"Content-type", "application/json; charset=utf-8"},body:JSON.stringify(params)})const data = await response.json()console.log(data)
}
封装Axios
我们可以基于Axios简易封装一个自己的网络请求库
async function httpGet(url, params) {const request = await axios.get(url, {params})return request
}
async function httpPost(url, data) {const request = await axios.post(url, data)return request
}axios.interceptors.request.use(function(config) {return config;
}, function(error) {return Promise.reject(error);
});axios.interceptors.response.use(function(response) {return response;
}, function(error) {return Promise.reject(error);
});export {httpGet,httpPost
}