Ajax 笔记:
Ajax 笔记(一)—— Ajax 入门
Ajax 笔记(二)—— Ajax 案例
Ajax 笔记(三)—— Ajax 原理
Ajax 笔记(四)—— Ajax 进阶
Ajax 笔记接口文档:https://apifox.com/apidoc/shared-fa9274ac-362e-4905-806b-6135df6aa90e/doc-842135
3. Ajax 原理
3.1 XMLHttpRequest
3.1.1 XHR 使用步骤
Ajax
是浏览器与服务器通信的技术,采用 XMLHttpRequest
对象相关代码。axios
是对 XHR
相关代码进行了封装,让我们只关心传递的接口参数。学习 XHR 就是了解 axios
内部与服务器交互过程的真正原理。
const xhr = new XMLHttpRequest()
xhr.open('请求方法', '请求url网址', true) // 异步
// 接收相应
xhr.addEventListener('loadend', () => {
// 响应结果
console.log(xhr.response)
})
// 发送请求
xhr.send()
// 终止请求
xhr.abort()
onreadystatechange()的定义是只要返回的状态码只要变化时就回调一次函数,而onload只有状态码为4时才能回调一次函数。onprogress()当状态码为3时,会执行这个函数。
当服务器正常的话基本上都会返回readyState 状态码0~4,但是不一定请求得到数据,所以有个http状态码来判断。
xhr.onreadystatechange = function(){
if (xhr.readyState == 4 && xhr.status == 200)
{
console.log(`请求成功并返回数据${this.responseText}`);
}
}
3.1.2 查询参数
原生 XHR 需要自己在 url 后面携带查询参数字符串,没有 axios
帮助我们把 params
参数拼接到 url 字符串后面了
/**
* 目标:使用XHR携带查询参数,展示某个省下属的城市列表
*/
const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://hmajax.itheima.net/api/city?pname=辽宁省')
xhr.addEventListener('loadend', () => {
console.log(xhr.response)
const data = JSON.parse(xhr.response)
console.log(data)
document.querySelector('.city-p').innerHTML = data.list.join('<br>')
})
xhr.send()
多个查询参数:
可以用 URLSearchParams
把参数对象转成 “参数名=值&参数名=值“ 格式的字符串
// 1. 创建 URLSearchParams 对象
const paramsObj = new URLSearchParams({
参数名1: 值1,
参数名2: 值2
})
// 2. 生成指定格式查询参数字符串
const queryString = paramsObj.toString()
// 结果:参数名1=值1&参数名2=值2
代码示例:
const xhr = new XMLHttpRequest()
const paramsObj = new URLSearchParams({
pname: '河北省',
cname: '石家庄市'
})
const queryString = paramsObj.toString()
xhr.open('GET', `http://hmajax.itheima.net/api/area?${queryString}`)
xhr.addEventListener('loadend', () => {
console.log(JSON.parse(xhr.response))
document.querySelector('.my-p').innerHTML = JSON.parse(xhr.response).list.join('<br>')
})
xhr.send()
3.1.3 数据提交
const xhr = new XMLHttpRequest()
xhr.open('请求方法', '请求url网址')
xhr.addEventListener('loadend', () => {
console.log(xhr.response)
})
// 1. 告诉服务器,我传递的内容类型,是 JSON 字符串
xhr.setRequestHeader('Content-Type', 'application/json')
// 2. 准备数据并转成 JSON 字符串
const user = { username: 'itheima007', password: '7654321' }
const userStr = JSON.stringify(user)
// 3. 发送请求体数据
xhr.send(userStr)
3.2 Promise
3.2.1 Promise 使用步骤
Promise 对象用于表示一个异步操作的最终完成(或失败)及其结构值,成功或失败会关联后续的处理函数。文章来源:https://www.toymoban.com/news/detail-641668.html
// 1. 创建 Promise 对象
const p = new Promise((resolve, reject) => {
// 2. 执行异步任务-并传递结果
// 成功调用: resolve(值) 触发 then() 执行
// 失败调用: reject(值) 触发 catch() 执行
})
// 3. 接收结果
p.then(result => {
// 成功
}).catch(error => {
// 失败
})
实例代码:文章来源地址https://www.toymoban.com/news/detail-641668.html
/**
* 目标:使用Promise管理异步任务
*/
// 1. 创建Promise对象
const p = new Promise((resolve, reject) => {
// 2. 执行异步代码
setTimeout(() => {
// resolve('模拟AJAX请求-成功结果')
reject(new Error('模拟AJAX请求-失败结果'))
}, 2000)
})
// 3. 获取结果
p.then(result => {
console.log(result)
}).catch(error => {
console.log(error)
})
3.2.2 Promise 状态
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝
- 已兑现(fulfilled):操作成功完成(调用.then(回调函数))
- 已拒绝(rejected):操作失败(调用.catch(回调函数))
3.2.3 Promise 和 XHR 应用小案例
/**
* 目标:使用Promise管理XHR请求省份列表
* 1. 创建Promise对象
* 2. 执行XHR异步代码,获取省份列表
* 3. 关联成功或失败函数,做后续处理
*/
// 1. 创建Promise对象
const p = new Promise((resolve, reject) => {
// 2. 执行XHR异步代码,获取省份列表
const xhr = new XMLHttpRequest()
xhr.open('GET', 'http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend', () => {
// xhr如何判断响应成功还是失败的?
// 2xx开头的都是成功响应状态码
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()
})
// 3. 关联成功或失败函数,做后续处理
p.then(result => {
console.log(result)
document.querySelector('.my-p').innerHTML = result.list.join('<br>')
}).catch(error => {
// 错误对象要用console.dir详细打印
console.dir(error)
// 服务器返回错误提示消息,插入到p标签显示
document.querySelector('.my-p').innerHTML = error.message
})
3.3 封装简易 axios
3.3.1 核心封装代码
/**
* 目标:封装_简易axios函数_获取省份列表
* 1. 定义myAxios函数,接收配置对象,返回Promise对象
* 2. 发起XHR请求,默认请求方法为GET
* 3. 调用成功/失败的处理程序
* 4. 使用myAxios函数,获取省份列表展示
*/
// 1. 定义myAxios函数,接收配置对象,返回Promise对象
function myAxios(config) {
return new Promise((resolve, reject) => {
// 2. 发起XHR请求,默认请求方法为GET
const xhr = new XMLHttpRequest()
xhr.open(config.method || 'GET', config.url)
xhr.addEventListener('loadend', () => {
// 3. 调用成功/失败的处理程序
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
// 4. 使用myAxios函数,获取省份列表展示
myAxios({
url: 'http://hmajax.itheima.net/api/province'
}).then(result => {
console.log(result)
document.querySelector('.my-p').innerHTML = result.list.join('<br>')
}).catch(error => {
console.log(error)
document.querySelector('.my-p').innerHTML = error.message
})
3.3.2 支持传递查询参数
function myAxios(config) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
// 1. 判断有params选项,携带查询参数
if (config.params) {
// 2. 使用URLSearchParams转换,并携带到url上
const paramsObj = new URLSearchParams(config.params)
const queryString = paramsObj.toString()
// 把查询参数字符串,拼接在url?后面
config.url += `?${queryString}`
}
xhr.open(config.method || 'GET', config.url)
xhr.addEventListener('loadend', () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
// 3. 使用myAxios函数,获取地区列表
myAxios({
url: 'http://hmajax.itheima.net/api/area',
params: {
pname: '辽宁省',
cname: '大连市'
}
}).then(result => {
console.log(result)
document.querySelector('.my-p').innerHTML = result.list.join('<br>')
})
3.3.3 支持传递请求体数据
function myAxios(config) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
if (config.params) {
const paramsObj = new URLSearchParams(config.params)
const queryString = paramsObj.toString()
config.url += `?${queryString}`
}
xhr.open(config.method || 'GET', config.url)
xhr.addEventListener('loadend', () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
// 1. 判断有data选项,携带请求体
if (config.data) {
// 2. 转换数据类型,在send中发送
const jsonStr = JSON.stringify(config.data)
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.send(jsonStr)
} else {
// 如果没有请求体数据,正常的发起请求
xhr.send()
}
})
}
document.querySelector('.reg-btn').addEventListener('click', () => {
// 3. 使用myAxios函数,完成注册用户
myAxios({
url: 'http://hmajax.itheima.net/api/register',
method: 'POST',
data: {
username: 'itheima999',
password: '666666'
}
}).then(result => {
console.log(result)
}).catch(error => {
console.dir(error)
})
})
```
到了这里,关于Ajax 笔记(三)—— Ajax 原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!