14 实现Ajax
步骤
- 创建
XMLHttpRequest实例 - 发出 HTTP 请求
- 服务器返回 XML 格式的字符串
- JS 解析 XML,并更新局部页面
- 不过随着历史进程的推进,XML 已经被淘汰,取而代之的是 JSON。
了解了属性和方法之后,根据 AJAX 的步骤,手写最简单的 GET 请求。
1 原生实现
function ajax() {
let xhr = new XMLHttpRequest() //实例化,以调用方法
xhr.open('get', 'https://www.google.com') //参数2,url。参数三:异步
xhr.onreadystatechange = () => { //每当 readyState 属性改变时,就会调用该函数。
if (xhr.readyState === 4) { //XMLHttpRequest 代理当前所处状态。
if (xhr.status >= 200 && xhr.status < 300) { //200-300请求成功
let string = xhr.responseText
//JSON.parse() 方法用来解析JSON字符串,构造由字符串描述的JavaScript值或对象
let object = JSON.parse(string)
}
}
}
xhr.send() //用于实际发出 HTTP 请求。不带参数为GET请求
}
2 Promise实现
基于Promise封装Ajax
- 返回一个新的
Promise实例 - 创建
HMLHttpRequest异步对象 - 调用
open方法,打开url,与服务器建立链接(发送前的一些处理) - 监听
Ajax状态信息 - 如果
xhr.readyState == 4(表示服务器响应完成,可以获取使用服务器的响应了)xhr.status == 200,返回resolve状态xhr.status == 404,返回reject状态
xhr.readyState !== 4,把请求主体的信息基于send发送给服务器
function ajax(url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.open('get', url)
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status <= 300) {
resolve(JSON.parse(xhr.responseText))
} else {
reject('请求出错')
}
}
}
xhr.send() //发送hppt请求
})
}
let url = '/data.json'
ajax(url).then(res => console.log(res))
.catch(reason => console.log(reason))
补充(现代做法):现在业务里几乎不再手写
XMLHttpRequest,而是用fetch(返回 Promise,需用AbortController取消、并自行处理 HTTP 错误码——fetch只在网络失败时 reject,4xx/5xx 不会 reject)。面试若问「fetch和XMLHttpRequest的区别」可答:fetch默认不带 cookie(需credentials: 'include')、无原生超时(用AbortSignal.timeout(ms))、无上传进度。async function request(url, { timeout = 8000, ...opts } = {}) { const res = await fetch(url, { signal: AbortSignal.timeout(timeout), ...opts }) if (!res.ok) throw new Error(`HTTP ${res.status}`) // fetch 不会因 4xx/5xx 而 reject return res.json() }
