目录
- 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
请求通常分为四步
- 创建
XMLHTTPRequest
const 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 = timeout
xhr.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
请求文章来源:https://uudwc.com/A/k9ypX
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
简易封装一个自己的网络请求库文章来源地址https://uudwc.com/A/k9ypX
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
}