简明扼要的axios使用指南
- 前言:axios是什么;ajax是什么;axios和ajax有什么关系
- 一、url
- 二、常用请求方法
- 1.axios的引入:
- 2.get
- 3.post
- 4.在返回结果里找需要的数据:
- 三、接口文档
- 1.接口文档是什么:
- 2.接口是什么:
- 四、使用form-serialize插件快速获取表单元素的值
- 1.步骤:
- 2.写法
- 五、Bootstrap弹框
- 1.作用:
- 2.步骤
- 六、上传图片
- 1.步骤:
- 2.代码/写法:
- 七、XMLHttpRequest对象(简称XHR)
- 1.作用:
- 2.步骤:
- 3.xhr如何判断响应成功还是失败的
- 八、promis对象
- 1.什么是异步代码:
- 2.promis是用来干嘛的:
- 3.promis对象的状态
- 九、promis+XHR
- 1.xhr如何判断响应成功还是失败的
- 2.错误对象要用console.dir详细打印
- 十、promis+XHR封装自定义的myAxios函数
- 1.步骤:
- 2.代码:
- 十一、promise链式调用
- 1.案例的需求:
- 2.不好的写法:回调函数地狱。
- 3.解决方法一:promise链式调用(不是最简洁)(但也要掌握)
- 步骤:
- 代码:
- 4.解决方法二:通过使用 async函数和await关键字 解决
- async函数是什么:
- 步骤:
- 代码:(栗子)
- 5.在js中如何捕获异常:
- 十二、事件循环
- 1. 是什么:
- 2.执行过程:
- 3.同步|异步:
- 什么是同步代码?
- 什么是异步代码?
- 4.宏任务|微任务有哪些:
- 十三、promise.all静态方法
- 1.作用:
- 2.写法:
- 3.应用场景:
- 4.案例:
前言:axios是什么;ajax是什么;axios和ajax有什么关系
- axios是什么?
①axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
②axios是 vue 官方推荐使用的 http 库。 - ajax是什么?
①Ajax 并非编程语言。
②Ajax 通过与场景后面的 Web 服务器交换数据来异步更新网页。这意味着可以更新网页的部分,而不需要重新加载整个页面。 - axios和ajax有什么关系?
①“实现ajax的方式有多种,如jQuery封装的ajax,原生的XMLHttpRequest,以及axios。”
=>axios是其中一种实现ajax的方法。
②“promise 把 ajax 进行封装,成了 axios”
一、url
url的构成:协议+域名+资源路径
二、常用请求方法
1.axios的引入:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
2.get
axios({
url: 'http://hmajax.itheima.net/api/city',
params: {//在params里传递要查询的参数
参数名: 参数值,
参数名: 参数值
//params里的参数会被编码成查询字符串,拼到路径后面
}
}).then(result => {
//请求成功执行的代码
}).catch(error => {
//请求失败执行的代码
})
3.post
axios({
url: '',
method: 'POST',//get默认、可省;不区分大小写
data: {//提交数据用data
属性名:属性值,
属性名:属性值
//或者:
被复制的变量,
被复制的变量
}
}).then(result => {
//请求成功执行的代码
}).catch(error => {
//请求失败执行的代码
})
请求方法:put 操作:修改数据(全部)
请求方法:delete 操作:删除数据
请求方法:patch 操作:修改数据(部分)
4.在返回结果里找需要的数据:
F12,控制台,右键,复制属性路径
axios({
url: 'http://hmajax.itheima.net/api/login',
method: 'POST',
data: {
username,
password
}
}).then(result => {
console.log(result)
console.log(result.data.message)
//输出登录成功//怎么找到这些东西呢?在F12控制台里输出的结果里面找,
//找到之后右键,复制属性路径。
}).catch(error => {
console.log(error)
console.log(error.response.data.message)//输出用户或密码错误
})
})
三、接口文档
1.接口文档是什么:
描述接口的文章。
2.接口是什么:
就是我们使用的URL,请求方法,参数。
四、使用form-serialize插件快速获取表单元素的值
1.步骤:
- 引入插件(下载的js文件)
- 给表单元素设置name属性(设置一个名字);
[name属性的值最好和data、params里的参数名一致]。 - 调用函数 两个参数:serialize(捕获的表单元素, { hash: true, empty: true }(配置对象)); 这个函数将返回一个对象,对象里的属性名=第二点,属性值=用户输入的值。
- empty 设置是否获取空值
- true: 获取空值(推荐)
- false:不获取空值
- hash 设置获取数据结构
- true:JS对象(推荐)
- false: 查询字符串
2.写法
<form class="login-form">
<input type="text" class="form-control username" name="username">
<input type="password" class="form-control password" name="password">
</form>
<script src="./lib/form-serialize.js"></script>
<script>
document.querySelector('.btn-login').addEventListener('click', () => {
// 3.2 使用serialize函数,收集登录表单里用户名和密码
const form = document.querySelector('.login-form')
const data = serialize(form, { hash: true, empty: true })
console.log(data)
})
</script>
五、Bootstrap弹框
1.作用:
在不离开当前页面的情况下,出现弹窗供用户操作
2.步骤
1.引入bootstrap.css和bootstrap.js
<!-- 引入bootstrap.css -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- 引入bootstrap.js -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js"></script>
</body>//(在最下面引用)
2.准备弹窗的布局:bootstrap文档里搜modal,找到需要的模板复制粘贴过来
-
制弹框显示隐藏的方法
①通过设置按钮的属性,控制弹窗的显示和隐藏
“bootstrap弹窗带有自定义属性,可控制弹框的显示和隐藏”
要使用这个功能,从文档里面复制过来,就会有一个类名modal以及自动引入一个css类,若有多个弹窗,则多个弹窗都会有一个类名:modal。无法区分,
因此,单击按钮显示弹窗时,还要给加一个他单独拥有的类选择器
②通过js控制弹窗的显示和隐藏
“调用弹窗对象内置的show和hide方法”
六、上传图片
1.步骤:
-
获取图片文件
-
实例化一个表单数据对象,该对象内置了一个append方法,使用该方法像对象中添加参数名和值
-
将表单对象提交给服务器,服务器会将它保存起来,并返回图片的url网址
-
将该url网址用在img标签里,展示图片
2.代码/写法:
document.querySelector('.upload').addEventListener('change', e => {
// 1. 获取图片文件
console.log(e.target.files[0])
// 文件保存在了文件选择元素<input type="file" class="upload">里,e.target指的是触发事件的元素
//e.target.files拿到文件选择元素里的文件列表(是个为数组),文件对象在files[0]里面
// 2. 使用 FormData 携带图片文件
const fd = new FormData()
fd.append('img', e.target.files[0])
// 3. 提交到服务器,获取图片url网址使用
axios({
url: 'http://hmajax.itheima.net/api/uploadimg',
method: 'POST',
data: fd//不用写大括号,传的不是对象,是一个表单数据
}).then(result => {
console.log(result)
// 取出图片url网址,用img标签加载显示
const imgUrl = result.data.data.url//f12->控制台->右键复制属性路径
document.querySelector('.my-img').src = imgUrl
})
})
七、XMLHttpRequest对象(简称XHR)
1.作用:
用于与服务器交互,允许页面在不影响用户操作的情况下刷新部分内容。
静态页面只有一两个地方与服务器交互的地方可用。
2.步骤:
- 实例化XMLHttpRequest对象
- xhr.open配置请求方法和请求 url 地址
- 设置loadend 事件监听,xhr.response接收响应结果。【注:是一个json字符串,要用转成js对象JSON.parse(xhr.response)】
- xhr.send()真正发起一次网络请求
3.xhr如何判断响应成功还是失败的
// xhr如何判断响应成功还是失败的?
// 2xx开头的都是成功响应状态码
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
八、promis对象
1.什么是异步代码:
耗时,但不会阻塞代码继续执行
2.promis是用来干嘛的:
成功的话,调用resolve函数,传入的参数是result。
失败调用reject函数,传入的参数是一个错误的对象。
一个不一定对,但便于理解的东西:
- 传给resolve/reject函数的参数即为传给result/error的参数。
- 如果没传,then里的形参result就是发起请求得到的结果(比如你要查询中国所有省份的信息,形参result就会得到这个信息)
3.promis对象的状态
九、promis+XHR
-
以get请求为例,了解两个要点:
1.xhr如何判断响应成功还是失败的
const p = new Promise((resolve, reject) => { 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))//JSON.parse将json字符串转成js对象 } else { reject(new Error(xhr.response)) } }) xhr.send() })
2.错误对象要用console.dir详细打印
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 })
十、promis+XHR封装自定义的myAxios函数
1.步骤:
这里之所以要返回一个promise对象,是因为用promise的时候,结果返回给的是实例p,实例p去调用请求成功的函数then和请求失败的函数catch。return其实就是代替了那个实例p的位置。
2.代码:
(适用于所有请求)
// 1. 定义myAxios函数,接收配置对象,返回Promise对象
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()
})
}
// 调用封装的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>')
})
十一、promise链式调用
1.案例的需求:
默认赋予第一个省份名字,获得了省份之后,自动获取并展示该省份的的一个城市,该省份该城市的第一个城区。(并显示再下拉列表中)
-
html
<form> <span>省份:</span> <select> <option class="province"></option> </select> <span>城市:</span> <select> <option class="city"></option> </select> <span>地区:</span> <select> <option class="area"></option> </select> </form>
2.不好的写法:回调函数地狱。
- 什么是回调函数地狱?
在回调函数一直向下嵌套回调函数,形成回调函数地狱。 - 回调函数地狱问题?
可读性差,异常捕获困难,耦合性严重。 - 回调函数地狱代码:
axios({url: 'http://hmajax.itheima.net/api/province'}).then(result => { const pname = result.data.list[0] document.querySelector('.province').innerHTML = pname // 2. 获取默认第一个城市的名字 axios({url: 'http://hmajax.itheima.net/api/city', params: { pname }}).then(result => { const cname = result.data.list[0] document.querySelector('.city').innerHTML = cname // 3. 获取默认第一个地区的名字 axios({url: 'http://hmajax.itheima.net/api/area', params: { pname, cname }}).then(result { console.log(result) const areaName = result.data.list[0] document.querySelector('.area').innerHTML = areaName }) }) })
- 如何解决:
- 应该用线性串联的结构,而非回调的结构
- 解决方法一:promise链式调用
- 解决方法二:使用 async函数和await关键字
3.解决方法一:promise链式调用(不是最简洁)(但也要掌握)
步骤:
代码:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script> /** * 目标:把回调函数嵌套代码,改成Promise链式调用结构 * 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中 */ let pname = '' // 1. 得到-获取省份Promise对象 axios({url: 'http://hmajax.itheima.net/api/province'}).then(result => { pname = result.data.list[0] document.querySelector('.province').innerHTML = pname // 2. 得到-获取城市Promise对象 return axios({url: 'http://hmajax.itheima.net/api/city', params: { pname }}) }).then(result => { const cname = result.data.list[0] document.querySelector('.city').innerHTML = cname // 3. 得到-获取地区Promise对象 return axios({url: 'http://hmajax.itheima.net/api/area', params: { pname, cname }}) }).then(result => { console.log(result) const areaName = result.data.list[0] document.querySelector('.area').innerHTML = areaName }) </script> </body>
4.解决方法二:通过使用 async函数和await关键字 解决
async函数是什么:
是使用async关键字声明的函数
步骤:
- 把async关键字写在函数声明的前面;
- axios前使用await关键词,await关键字会暂停代码继续往下执行,直到axios请求返回结果,并将这个结果提取在原地。
const pObj = await axios({url:'http://hmajax.itheima.net/api/province'})
然后将结果赋值给一个对象。代码:(栗子)
// 1. 定义async修饰函数 async function getData() { // 2. await等待Promise对象成功的结果 const pObj = await axios({url: 'http://hmajax.itheima.net/api/province'}) const pname = pObj.data.list[0] const cObj = await axios({url: 'http://hmajax.itheima.net/api/city', params: { pname }}) const cname = cObj.data.list[0] const aObj = await axios({url: 'http://hmajax.itheima.net/api/area', params: { pname, cname }}) const areaName = aObj.data.list[0] document.querySelector('.province').innerHTML = pname document.querySelector('.city').innerHTML = cname document.querySelector('.area').innerHTML = areaName } //调用这个async修饰的函数 getData()
5.在js中如何捕获异常:
使用try和catch(js都可以这样捕获异常)
十二、事件循环
1. 是什么:
执行代码和收集异步任务的模型
2.执行过程:
异步代码放到宿主环境中执行(宿主环境将异步代码执行的顺序排列,放到任务队列中),在任务队列中排队,当调用栈空的时候,执行任务队列。
任务队列又分为宏任务队列和微任务队列;
先执行微任务队列,再执行宏任务队列
3.同步|异步:
什么是同步代码?
逐行执行,上一行执行完才会执行下一行。
什么是异步代码?
耗时,不必等待代码执行完成,不阻塞代码继续执行。【执行完成有结果后,会通过回调函数将结果传回来。】
new Promise((resolve, reject) => {
本身是同步的, .then(result => {})
(回调函数)是异步的。
4.宏任务|微任务有哪些:
异步代码分为宏任务和微任务;
回调函数是异步代码。
十三、promise.all静态方法
1.作用:
合并多个promis对象,等待所有都成功或某一个失败后,做后续逻辑。
2.写法:
const p = Promise.all([Promise对象1, Promise对象2, Promise对象3, ...])
p.then(result => {
}).catch(error => {
})
3.应用场景:
当我需要同一时间显示多个请求的结果时,就要把多请求合并
4.案例:
显示"北京", “上海”, “广州”, "深圳"的天气在首页查看
代码:
<body>
<ul class="my-ul"></ul>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 1. 请求城市天气,得到Promise对象
const bjPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '110100' } })
const shPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '310100' } })
const gzPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '440100' } })
const szPromise = axios({ url: 'http://hmajax.itheima.net/api/weather', params: { city: '440300' } })
const p = Promise.all([bjPromise, shPromise, gzPromise, szPromise])
// 2. 使用Promise.all,合并多个Promise对象
p.then(result => {
// 注意:结果数组顺序和合并时顺序是一致
console.log(result)
const htmlStr = result.map(item => {
return `<li>${item.data.data.area} --- ${item.data.data.weather}</li>`
}).join('')
document.querySelector('.my-ul').innerHTML = htmlStr
}).catch(error => {
console.dir(error)
})
</script>
</body>
```