浏览器和服务器之间通信,动态数据交互
引入axios库
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>
使用axios函数
axios({
url: 'http://hmajax.itheima.net/api/province'
}).then(result => {
document.write(result['data']['list'].join('<br>'))
})
浏览器提供给服务器的额外信息,让服务器返回浏览器想要的数据
axios({
url: 'http://hmajax.itheima.net/api/city',
params: {
pname: '河南省'
}
}).then(result => {
document.write(result.data.list.join(' '))
})
axios({
url: 'http://hmajax.itheima.net/api/register',
method: 'post',
// 请求体携带的信息
data: {
username,
password
}
}).then(result => {
p.innerText = result['data']['message']
}).catch(error => {
p.innerText = error['response']['data']['message']
})
作用:快速收集表单元素的值
document.querySelector('button').addEventListener('click', () => {
const form = document.querySelector('.test-form')
const data = serialize(form, {
hash: true,
empty: true
})
console.log(data)
})
const fd = new FormData()
fd.append(参数名, 值)
document.querySelector('.upload').addEventListener('change', e => {
// 1. 获取图片文件
console.log(e.target.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
document.querySelector('.my-img').src = imgUrl
})
})
// 设置本地存储
localStorage.setItem('url', imgUrl)
// 读取本地存储
const imgUrl = localStorage.getItem('url')
axios.default.baseURI = 'http://geek.itheima.net'
const xhr = new XMLHttpRequest()
const pname = '河北省'
xhr.open('get', `http://hmajax.itheima.net/api/city?pname=${pname}`)
xhr.addEventListener('loadend', e => {
console.log(JSON.parse(e.explicitOriginalTarget.responseText).list)
})
xhr.send()
使用urlSearchParams
对象简化操作
const obj = {
name: 'wmh',
gender: 'man'
}
console.log((new URLSearchParams(obj)).toString())
// 'name=wmh&gender=man'
const xhr = new XMLHttpRequest()
xhr.open('POST','http://hmajax.itheima.net/api/register')
// 设置Content-Type: application/json
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.addEventListener('loadend', e => {
console.log(e.explicitOriginalTarget.response)
})
const obj = {
username : 'wmh12345678',
password : 'wmh123456',
}
// 携带JSON字符串
xhr.send(JSON.stringify(obj))
Promise:一个异步操作最终状态和结果值的对象
用于管理异步操作的代码,解决回调函数地狱的问题
// 1. 创建 Promise 对象
const p = new Promise((resolve, reject) => {
// 2. 执行异步任务-并传递结果
// 成功调用: resolve(值) 触发 then() 执行
// 失败调用: reject(值) 触发 catch() 执行
})
// 3. 接收结果
p.then(result => {
// 成功
}).catch(error => {
// 失败
})
通过status
状态码判断是否请求成功
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('POST', 'http://hmajax.itheima.net/api/register')
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.addEventListener('loadend', e => {
if (e.explicitOriginalTarget.status >= 200 && e.explicitOriginalTarget.status < 300) {
resolve('注册成功')
} else {
reject(new Error('注册失败'))
}
})
const obj = {
username: 'wmh123456',
password: 'wmh123456',
}
xhr.send(JSON.stringify(obj))
})
p.then(r => {
console.log(r)
}).catch(e => {
console.log(e)
})
每个 Promise 对象一旦被兑现/拒绝,那就是已敲定了,状态无法再被改变
在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱
缺点:可读性差,异常无法捕获,耦合性严重,牵一发动全身
let pname, cname
axios({
url: 'http://hmajax.itheima.net/api/province'
}).then(r => {
pname = r.data.list[0]
document.querySelector('.province').innerHTML = pname
axios({
url: 'http://hmajax.itheima.net/api/city',
params: {pname}
}).then(r => {
cname = r.data.list[0]
document.querySelector('.city').innerHTML = cname
axios({
url: 'http://hmajax.itheima.net/api/area',
params: {pname, cname}
}).then(r => {
document.querySelector('.area').innerHTML = r.data.list[0]
})
})
})
Promise 链式调用:依靠 then() 方法会返回一个新生成的 Promise 对象特性,继续串联下一环任务,直到结束
let pname = ''
axios({url: 'http://hmajax.itheima.net/api/province'}).then(result => {
pname = result.data.list[0]
document.querySelector('.province').innerHTML = pname
return axios({url: 'http://hmajax.itheima.net/api/city', params: {pname}})
}).then(result => {
const cname = result.data.list[0]
document.querySelector('.city').innerHTML = cname
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
})
在 async 函数内,使用 await 关键字取代 then 函数,等待获取 Promise 对象成功状态的结果值
async function getData() {
const province = await axios({url: 'http://hmajax.itheima.net/api/province'})
const pname = province.data.list[0]
const city = await axios({url: 'http://hmajax.itheima.net/api/city', params: {pname}})
const cname = city.data.list[0]
const area = await axios({url: 'http://hmajax.itheima.net/api/area', params: {pname, cname}})
const aname = area.data.list[0]
document.querySelector('.area').innerHTML = aname
document.querySelector('.province').innerHTML = pname
document.querySelector('.city').innerHTML = cname
}
getData()
语句标记要尝试的语句块,并指定一个出现异常时抛出的响应
try 里有报错的代码,会立刻跳转到 catch 中
try {
// 要执行的代码
} catch (error) {
// error 接收的是,错误消息
// try 里代码,如果有错误,直接进入这里执行
}
宏任务每次在执行同步代码时,产生微任务队列,清空微任务队列任务后,微任务队列空间释放!
下一次宏任务执行时,遇到微任务代码,才会再次申请微任务队列空间放入回调函数消息排队
总结:一个宏任务包含微任务队列,他们之间是包含关系,不是并列关系
合并多个 Promise 对象并等待所有同时成功的结果,如果有一个报错就会最终为失败状态,当需要同时渲染多个接口数据同时到网页上时使用
const p = Promise.all([Promise对象, Promise对象, ...])
p.then(result => {
// result 结果: [Promise对象成功结果, Promise对象成功结果, ...]
}).catch(error => {
// 失败的 Promise 抛出的异常对象
})