当前位置: 首页 > news >正文

AJAX前端与后端交互技术知识点以及案例

Promise

promise对象用于表示一个异步操作的最终完成(或失败)及其结果值

好处:

  1. 逻辑更清晰
  2. 了解axios函数内部运作机制
  3. 成功和失败状态,可以关联对应处理程序
  4. 能解决回调函数地狱问题

    /*** 目标:使用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)})

Promise - 三种状态

作用:了解Promise对象如何关联的处理函数,以及代码的执行顺序

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝
  • 已兑现:意味着,操作成功完成
  • 已拒绝:意味着,操作失败

注意:Promise对象一旦被兑现/拒绝,就是已经敲定了,状态无法再被改变

    /*** 目标:认识Promise状态*/// 1. 创建Promise对象(pending-待定状态)const p = new Promise((resolve, reject) => {// Promise对象创建时,这里的代码都会执行了// 2. 执行异步代码setTimeout(() => {// resolve() => 'fulfilled状态-已兑现' => then()resolve('模拟AJAX请求-成功结果')// reject() => 'rejected状态-已拒绝' => catch()reject(new Error('模拟AJAX请求-失败结果'))}, 2000)})console.log(p)// 3. 获取结果p.then(result => {console.log(result)}).catch(error => {console.log(error)})

使用Promise+XHR获取省份列表

需求:使用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})

封装_简易axios_获取省份列表

需求:基于Promise+XHR封装myAxios函数,获取省份列表展示

步骤:

  1. 发起myAxios函数,接收配置对象,返回Promise对象
  2. 发起XHR请求,默认请求方法为GET
  3. 调用成功/失败的处理程序
  4. 使用myAxios函数,获取省份列表展示
    /*** 目标:封装_简易axios函数_获取省份列表*  1. 定义myAxios函数,接收配置对象,返回Promise对象*  2. 发起XHR请求,默认请求方法为GET*  3. 调用成功/失败的处理程序*  4. 使用myAxios函数,获取省份列表展示*/// 1. 定义myAxios函数,接收配置对象,返回Promise对象function myAxios(config) {return new Promise((resolve, reject) => {// 2. 发起XHR请求,默认请求方法为GETconst 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})

封装_简易axios_获取地区列表、

需求:修改myAxios函数支持传递查询参数,获取"辽宁省"、"大连市"对应地区列表展示

    /*** 目标:封装_简易axios函数_获取地区列表*  1. 判断有params选项,携带查询参数*  2. 使用URLSearchParams转换,并携带到url上*  3. 使用myAxios函数,获取地区列表*/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>')})

封装_简易_axios_注册用户

需求:修改myAxios函数支持传递请求体数据,完成用户注册功能

步骤:

  1. myaxios函数调用后,判断data选项
  2. 转换数据类型,在send方法中发送
  3. 使用自己封装的myAxios函数完成注册用户功能
    /*** 目标:封装_简易axios函数_注册用户*  1. 判断有data选项,携带请求体*  2. 转换数据类型,在send中发送*  3. 使用myAxios函数,完成注册用户*/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)//需要自己手动设置传递内容类型为json字符串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)})})

案例 - 天气预报

步骤:

  1. 获取北京市天气数据,展示
  2. 搜索城市列表,展示
  3. 点击城市,显示对应天气数据

/*** 目标1:默认显示-北京市天气*  1.1 获取北京市天气数据*  1.2 数据展示到页面*/
// 获取并渲染城市天气函数
function getWeather(cityCode) {// 1.1 获取北京市天气数据myAxios({url: 'http://hmajax.itheima.net/api/weather',params: {city: cityCode}}).then(result => {console.log(result)const wObj = result.data// 1.2 数据展示到页面// 阳历和农历日期const dateStr = `<span class="dateShort">${wObj.date}</span><span class="calendar">农历&nbsp;<span class="dateLunar">${wObj.dateLunar}</span></span>`document.querySelector('.title').innerHTML = dateStr// 城市名字document.querySelector('.area').innerHTML = wObj.area// 当天气温const nowWStr = `<div class="tem-box"><span class="temp"><span class="temperature">${wObj.temperature}</span><span>°</span></span></div><div class="climate-box"><div class="air"><span class="psPm25">${wObj.psPm25}</span><span class="psPm25Level">${wObj.psPm25Level}</span></div><ul class="weather-list"><li><img src="${wObj.weatherImg}" class="weatherImg" alt=""><span class="weather">${wObj.weather}</span></li><li class="windDirection">${wObj.windDirection}</li><li class="windPower">${wObj.windPower}</li></ul></div>`document.querySelector('.weather-box').innerHTML = nowWStr// 当天天气const twObj = wObj.todayWeatherconst todayWStr = `<div class="range-box"><span>今天:</span><span class="range"><span class="weather">${twObj.weather}</span><span class="temNight">${twObj.temNight}</span><span>-</span><span class="temDay">${twObj.temDay}</span><span>℃</span></span></div><ul class="sun-list"><li><span>紫外线</span><span class="ultraviolet">${twObj.ultraviolet}</span></li><li><span>湿度</span><span class="humidity">${twObj.humidity}</span>%</li><li><span>日出</span><span class="sunriseTime">${twObj.sunriseTime}</span></li><li><span>日落</span><span class="sunsetTime">${twObj.sunsetTime}</span></li></ul>`document.querySelector('.today-weather').innerHTML = todayWStr// 7日天气预报数据展示const dayForecast = wObj.dayForecastconst dayForecastStr = dayForecast.map(item => {return `<li class="item"><div class="date-box"><span class="dateFormat">${item.dateFormat}</span><span class="date">${item.date}</span></div><img src="${item.weatherImg}" alt="" class="weatherImg"><span class="weather">${item.weather}</span><div class="temp"><span class="temNight">${item.temNight}</span>-<span class="temDay">${item.temDay}</span><span>℃</span></div><div class="wind"><span class="windDirection">${item.windDirection}</span><span class="windPower">${item.windPower}</span></div></li>`}).join('')// console.log(dayForecastStr)document.querySelector('.week-wrap').innerHTML = dayForecastStr})
}// 默认进入网页-就要获取天气数据(北京市城市编码:'110100')
getWeather('110100')/*** 目标2:搜索城市列表*  2.1 绑定input事件,获取关键字*  2.2 获取展示城市列表数据*/
// 2.1 绑定input事件,获取关键字
document.querySelector('.search-city').addEventListener('input', (e) => {console.log(e.target.value)// 2.2 获取展示城市列表数据myAxios({url: 'http://hmajax.itheima.net/api/weather/city',params: {city: e.target.value}}).then(result => {console.log(result)const liStr = result.data.map(item => {return `<li class="city-item" data-code="${item.code}">${item.name}</li>`}).join('')console.log(liStr)document.querySelector('.search-list').innerHTML = liStr})
})/*** 目标3:切换城市天气*  3.1 绑定城市点击事件,获取城市code值*  3.2 调用获取并展示天气的函数*/
// 3.1 绑定城市点击事件,获取城市code值
document.querySelector('.search-list').addEventListener('click', e => {if (e.target.classList.contains('city-item')) {// 只有点击城市li才会走这里const cityCode = e.target.dataset.codeconsole.log(cityCode)// 3.2 调用获取并展示天气的函数getWeather(cityCode)}
})

同步代码和异步代码

同步代码:浏览器按照我们书写代码的顺序一行一行执行程序的,浏览器会等待代码的解析和工作,在上一行完成之后才会执行下一行,这样做是很有必要的,因为每一行新的代码都是建立在前面代码的基础之上的。

异步代码:使程序可在执行一个可能长期运行的任务的同时继续对其他事件作出反应而不必等待任务完成,与此同时,程序也将在任务完成后显示结果

 同步代码:逐行执行,需原地等待结果后,才可继续向下执行

异步代码:调用后耗时,不阻塞代码继续执行(不必原地等待),在将来完成后触发一个回调函数

回调函数地狱

 需求:展示默认第一个省,第一个城市,第一个地区在下拉菜单中

 概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱

缺点:可读性差,异常无法捕获,耦合性严重,牵一发动全身

    /*** 目标:演示回调函数地狱* 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中* 概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱* 缺点:可读性差,异常无法获取,耦合性严重,牵一发动全身*/// 1. 获取默认第一个省份的名字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})})}).catch(error => {console.dir(error)})

Promise - 链式调用

概念:依靠then()方法会返回一个新生成的Promise对象特性,继续串联下一环任务,直到结束

 细节:then()回调函数中的返回值,会影响新生成的Promise对象最终状态和结果

好处:通过链式调用,解决回调函数嵌套问题

    /*** 目标:掌握Promise的链式调用* 需求:把省市的嵌套结构,改成链式调用的线性结构*/// 1. 创建Promise对象-模拟请求省份名字const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('北京市')}, 2000)})// 2. 获取省份名字const p2 = p.then(result => {console.log(result)// 3. 创建Promise对象-模拟请求城市名字// return Promise对象最终状态和结果,影响到新的Promise对象return new Promise((resolve, reject) => {setTimeout(() => {resolve(result + '--- 北京')}, 2000)})})// 4. 获取城市名字p2.then(result => {console.log(result)})// then()原地的结果是一个新的Promise对象console.log(p2 === p)

Promise链式应用

目标:使用Promise链式调用,解决回调函数地狱问题

做法:每个Promise对象中管理一个异步任务,用then返回Promise对象,串联起来

    /*** 目标:把回调函数嵌套代码,改成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})

async函数(修饰函数)和await

async函数是使用async关键字声明的函数,async函数是AsyncFunction构造函数的实例,并且其中允许使用await关键字,async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise

概念:在async函数内,使用await关键字取代then函数,等待获取Promise对象成功状态的结果值

 用async和await也可直接获得promise对象返回的结果,不使用.then

    /*** 目标:掌握async和await语法,解决回调函数地狱* 概念:在async函数内,使用await关键字,获取Promise对象"成功状态"结果值* 注意:await必须用在async修饰的函数内(await会阻止"异步函数内"代码继续执行,原地等待结果)*/// 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 = pnamedocument.querySelector('.city').innerHTML = cnamedocument.querySelector('.area').innerHTML = areaName}getData()

async函数和await_捕获错误

使用try...catch

try...catch语句标记要尝试的语句块,并指定一个出现异常时抛出的响应

    /*** 目标:async和await_错误捕获*/async function getData() {// 1. try包裹可能产生错误的代码try {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 = pnamedocument.querySelector('.city').innerHTML = cnamedocument.querySelector('.area').innerHTML = areaName} catch (error) {// 2. 接着调用catch块,接收错误信息// 如果try里某行代码报错后,try中剩余的代码不会执行了console.dir(error)}}getData()

 认识 - 事件循环(EventLoop)

概念:JavaScript有一个基于事件循环的并发类型,事件循环负责执行代码,收集和处理事件以及执行队列中的子任务,这个模型与其它语言中的模型截然不同,比如C和Java。

原理:JavaScript单线程(某一刻只能执行一行代码),为了让耗时代码不阻塞其他代码运行,设计了事件循环模型

事件循环 - 执行过程

定义:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫事件循环

    // 目标:回答代码执行顺序console.log(1)setTimeout(() => {console.log(2)const p = new Promise(resolve => resolve(3))p.then(result => console.log(result))}, 0)const p = new Promise(resolve => {setTimeout(() => {console.log(4)}, 0)resolve(5)})p.then(result => console.log(result))const p2 = new Promise(resolve => resolve(6))p2.then(result => console.log(result))console.log(7)// 1 7 5 6 2 3 4

宏任务与微任务

ES6之后引入了Promise对象,让JS引擎也可以发起异步任务

异步任务分为:

  • 宏任务:由浏览器环境执行的异步代码
  • 微任务:由JS引擎环境执行的异步代码

宏任务:

任务(代码)执行所在环境
JS脚本执行事件浏览器
setTimeout/setInterval浏览器
AJAX请求完成事件浏览器
用户交互事件等浏览器

微任务:

任务(代码)执行所在环境
Promise对象.then()JS引擎

Promise本身是同步的,而then和catch回调函数是异步的

js内代码如何执行

  • 执行第一个script脚本事件宏任务,里面同步代码(先执行同步任务)
  • 遇到宏任务/微任务交给宿主环境,有结果回调函数进入对应队列(宏任务和微任务队列)
  • 当执行栈空闲时,清空微任务队列,再执行下一个宏任务(先执行微任务再执行宏任务)

    // 目标:回答代码执行顺序console.log(1)setTimeout(() => {console.log(2)const p = new Promise(resolve => resolve(3))p.then(result => console.log(result))}, 0)const p = new Promise(resolve => {setTimeout(() => {console.log(4)}, 0)resolve(5)})p.then(result => console.log(result))const p2 = new Promise(resolve => resolve(6))p2.then(result => console.log(result))console.log(7)// 1 7 5 6 2 3 4

Promise.all静态方法

概念:合并多个Promise对象,等待所有同时成功完成(或某一个失败),做后续逻辑

 

 需求:同时请求"北京","上海","广州","深圳"的天气并在网页中尽可能同时显示

    */// 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' } })// 2. 使用Promise.all,合并多个Promise对象const p = Promise.all([bjPromise, shPromise, gzPromise, szPromise])p.then(result => {//result为合并的promise对象返回的结果的数组// 注意:结果数组顺序和合并时顺序是一致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)})

商品分类

需求:尽可能同时展示所有商品分类到页面上

步骤:

  1. 获取所有的一级分类数据
  2. 遍历id,创建获取二级分类请求
  3. 合并所有二级分类Promise对象
  4. 等待同时成功,开始渲染页面
    /*** 目标:把所有商品分类“同时”渲染到页面上*  1. 获取所有一级分类数据*  2. 遍历id,创建获取二级分类请求*  3. 合并所有二级分类Promise对象*  4. 等待同时成功后,渲染页面*/// 1. 获取所有一级分类数据axios({url: 'http://hmajax.itheima.net/api/category/top'}).then(result => {console.log(result)// 2. 遍历id,创建获取二级分类请求const secPromiseList = result.data.data.map(item => {return axios({url: 'http://hmajax.itheima.net/api/category/sub',params: {id: item.id // 一级分类id}})})console.log(secPromiseList) // [二级分类请求Promise对象,二级分类请求Promise对象,...]// 3. 合并所有二级分类Promise对象const p = Promise.all(secPromiseList)p.then(result => {console.log(result)// 4. 等待同时成功后,渲染页面const htmlStr = result.map(item => {const dataObj = item.data.data // 取出关键数据对象return `<div class="item"><h3>${dataObj.name}</h3><ul>${dataObj.children.map(item => {return `<li><a href="javascript:;"><img src="${item.picture}"><p>${item.name}</p></a></li>`}).join('')}</ul></div>`}).join('')console.log(htmlStr)document.querySelector('.sub-list').innerHTML = htmlStr})})

 学习反馈 - 省市区切换

需求:完成省市区切换效果

步骤:

  1. 设置省份数据到下拉菜单
  2. 切换省份,设置城市数据到下拉菜单,并清空地区下拉菜单
  3. 切换城市,设置地区数据到下拉菜单
/*** 目标1:完成省市区下拉列表切换*  1.1 设置省份下拉菜单数据*  1.2 切换省份,设置城市下拉菜单数据,清空地区下拉菜单*  1.3 切换城市,设置地区下拉菜单数据*/
// 1.1 设置省份下拉菜单数据
axios({url: 'http://hmajax.itheima.net/api/province'
}).then(result => {const optionStr = result.data.list.map(pname => `<option value="${pname}">${pname}</option>`).join('')document.querySelector('.province').innerHTML = `<option value="">省份</option>` + optionStr
})// 1.2 切换省份,设置城市下拉菜单数据,清空地区下拉菜单
document.querySelector('.province').addEventListener('change', async e => {// 获取用户选择省份名字// console.log(e.target.value)const result = await axios({ url: 'http://hmajax.itheima.net/api/city', params: { pname: e.target.value } })const optionStr = result.data.list.map(cname => `<option value="${cname}">${cname}</option>`).join('')// 把默认城市选项+下属城市数据插入select中document.querySelector('.city').innerHTML = `<option value="">城市</option>` + optionStr// 清空地区数据document.querySelector('.area').innerHTML = `<option value="">地区</option>`
})// 1.3 切换城市,设置地区下拉菜单数据
document.querySelector('.city').addEventListener('change', async e => {console.log(e.target.value)const result = await axios({url: 'http://hmajax.itheima.net/api/area', params: {pname: document.querySelector('.province').value,cname: e.target.value}})console.log(result)const optionStr = result.data.list.map(aname => `<option value="${aname}">${aname}</option>`).join('')console.log(optionStr)document.querySelector('.area').innerHTML = `<option value="">地区</option>` + optionStr
})

学习反馈 - 数据提交

需求:收集学习反馈数据,提交保存

步骤:

  1. 监听提交按钮的点击事件
  2. 依靠插件收集表单数据
  3. 基于axios提交保存,显示结果
/*** 目标2:收集数据提交保存*  2.1 监听提交的点击事件*  2.2 依靠插件收集表单数据*  2.3 基于axios提交保存,显示结果*/
// 2.1 监听提交的点击事件
document.querySelector('.submit').addEventListener('click', async () => {// 2.2 依靠插件收集表单数据const form = document.querySelector('.info-form')const data = serialize(form, { hash: true, empty: true })console.log(data)// 2.3 基于axios提交保存,显示结果try {const result = await axios({url: 'http://hmajax.itheima.net/api/feedback',method: 'POST',data})console.log(result)alert(result.data.message)} catch (error) {console.dir(error)alert(error.response.data.message)}
})

相关文章:

AJAX前端与后端交互技术知识点以及案例

Promise promise对象用于表示一个异步操作的最终完成&#xff08;或失败&#xff09;及其结果值 好处&#xff1a; 逻辑更清晰了解axios函数内部运作机制成功和失败状态&#xff0c;可以关联对应处理程序能解决回调函数地狱问题 /*** 目标&#xff1a;使用Promise管理异步任…...

[AutoSar]BSW_Diagnostic_003 ReadDataByIdentifier(0x22)介绍

目录 关键词平台说明背景一、请求格式二、常用DID三、响应格式四、NRC五、case 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、diagnostic 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)au…...

买卖股票的最佳时机 II(LeetCode 122)

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…...

Spring Boot:让微服务开发像搭积木一样简单!

带你一探 Spring Boot 的自动配置和 Starter POMs 的神奇之处&#xff0c;展示如何通过几个简单的步骤就能让你的微服务应用在云端翱翔&#xff01; 文章目录 1. 引言1.1 简述Spring框架的起源与重要性1.2 阐述文章目的&#xff1a;深入解析Spring核心功能与应用实践2. 背景介绍…...

WordPress 、Typecho 站点的 MySQL/MariaDB 数据库优化

今天明月给大家分享一下 WordPress 、Typecho 站点的 MySQL/MariaDB 数据库优化&#xff0c;无论你的站点采用是 WordPress 还是 Typecho&#xff0c;都要用到 MySQL/MariaDB 数据库&#xff0c;我们以 MySQL 为主&#xff08;MariaDB 其实跟 MySQL 基本没啥大的区别&#xff0…...

==与===的区别

在许多编程语言和脚本语言中&#xff0c;包括 JavaScript 和 PHP 等&#xff0c; 和 是用于比较值的操作符。 “” 是相等运算符&#xff0c;用于比较两个值是否相等。它比较值时会进行类型转换&#xff0c;如果两个值在类型转换后相等&#xff0c;那么它们就被认为是相等的。…...

什么是ACID及基本实现的示例

什么是ACID特性 ACID 是一个缩写词&#xff0c;代表数据库事务的四个关键特性&#xff1a;原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;、持久性&#xff08;Durability&#xff09;。这些…...

【启明智显技术分享】SSD202核心板Rootfs下如何烧录mac地址

提示&#xff1a;作为Espressif&#xff08;乐鑫科技&#xff09;大中华区合作伙伴及sigmastar&#xff08;厦门星宸&#xff09;VAD合作伙伴&#xff0c;我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸…...

springboot3 集成spring-authorization-server (一 基础篇)

官方文档 Spring Authorization Server 环境介绍 java&#xff1a;17 SpringBoot&#xff1a;3.2.0 SpringCloud&#xff1a;2023.0.0 引入maven配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…...

AVL树!

文章目录 1.AVL树的概念2.AVL树的插入和旋转3.AVL树的旋转3.1旋转的底层&#xff1a;3.2 右旋转3.3 左旋转3.4 双旋 4.AVL树的底层 1.AVL树的概念 当向二叉搜索树中插入新结点后&#xff0c;如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整)&a…...

知识付费系统怎么安装教程,教师课堂教学该掌握哪些表达技巧?

课堂教学语言表达是教学艺术的一个基本且重要的组成部分。教师向学生传道、授业、解惑以及师生之间信息的传递和情感的交流&#xff0c;都离不开运用教学语言这一有力的工具&#xff0c;在课堂上&#xff0c;教师通过情趣盎然的表述&#xff0c;鞭辟入里的分析&#xff0c;恰到…...

基于MetaGPT的LLM Agent学习实战(一)

前言 我最近一直在做基于AI Agent 的个人项目&#xff0c; 因为工作加班较多&#xff0c;设计思考时间不足&#xff0c;这里借着Datawhale的开源学习课程《MetaGPT智能体理论与实战》课程&#xff0c;来完善自己的思路&#xff0c;抛砖引玉&#xff0c;和各位开发者一起学习&am…...

【IMX6ULL项目】IMX6ULL上Linux系统实现产测工具框架

电子产品量产测试与烧写工具。这是一套软件&#xff0c;用在我们的实际生产中&#xff0c; 有如下特点&#xff1a; 1.简单易用&#xff1a; 把这套软件烧写在 SD 卡上&#xff0c;插到 IMX6ULL 板子里并启动&#xff0c;它就会自动测试各个模块、烧写 EMMC 系统。 工人只要按…...

【Linux基础】Vim保姆级一键配置教程(手把手教你把Vim打造成高效率C++开发环境)

目录 一、前言 二、安装Vim 三、原始Vim编译器的缺陷分析 四、Vim配置 &#x1f95d;预备知识----.vimrc 隐藏文件 &#x1f34b;手动配置 Vim --- &#xff08;不推荐&#xff09; &#x1f347;自动化一键配置 Vim --- (强烈推荐) ✨功能演示 五、共勉 一、前言 Vim作为…...

Gartner发布准备应对勒索软件攻击指南:勒索软件攻击的三个阶段及其防御生命周期

攻击者改变了策略&#xff0c;在某些情况下转向勒索软件。安全和风险管理领导者必须通过提高检测和预防能力来为勒索软件攻击做好准备&#xff0c;同时还要改进其事后应对策略。 主要发现 勒索软件&#xff08;无加密的数据盗窃攻击&#xff09;是攻击者越来越多地使用的策略。…...

IB 公式解析

IB损失 自我感悟 根据对决策边界的影响程度来分配权重。影响程度越大&#xff0c;分配到的权重越小&#xff1b;影响程度越小&#xff0c;分配到的权重越大。 最后其实就是平衡因子和交叉熵损失的输出的乘积 公式 3.2. Influence Function 影响函数允许我们在移除样本时估…...

开发辅助工具的缩写

开发辅助工具的缩写有很多&#xff0c;这些工具通常是为了提高软件开发效率、代码质量和团队协作效率而设计的。以下是一些常见的开发辅助工具及其缩写&#xff1a; IDE - Integrated Development Environment&#xff08;集成开发环境&#xff09; VCS - Version Control Sys…...

linux程序分析命令(一)

linux程序分析命令(一) **ldd&#xff1a;**用于打印共享库依赖。这个命令会显示出一个可执行文件所依赖的所有共享库&#xff08;动态链接库&#xff09;&#xff0c;这对于解决运行时库依赖问题非常有用。**nm&#xff1a;**用于列出对象文件的符号表。这个命令可以显示出定…...

MYSQL数据库-SQL语句

数据库相关概念 名称全称简称数据库存储数据的仓库&#xff0c;数据是有组织的进行存储DataBase(DB)数据库管理系统操纵和管理数据库的大型软件DataBase Management System(DBMS)SQL操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库统一标准Structured Quer…...

MyBatis认识

一、定义 MyBatis是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;Plain Old Java O…...

【WEEK11】 【DAY6】Employee Management System Part 7【English Version】

2024.5.11 Saturday Continued from 【WEEK11】 【DAY5】Employee Management System Part 6【English Version】 Contents 10.8. Delete and 404 Handling10.8.1. Modify list.html10.8.2. Modify EmployeeController.java10.8.3. Restart10.8.4. 404 Page Handling10.8.4.1. …...

【52】Camunda8-Zeebe核心引擎-Clustering与流程生命周期

Clustering集群 Zeebe本质是作为一个brokers集群运行&#xff0c;形成一个点对点网络。在这个网络中&#xff0c;所有brokers的功能与服务都相同&#xff0c;没有单点故障。 Gossip协议 Zeebe实现了gossip协议&#xff0c;并借此知悉哪些broker当前是集群的一部分。 集群使用…...

从零开始的软件测试学习之旅(八)jmeter线程组参数化及函数学习

jmeter线程组参数化及函数学习 Jmeter基础基本使用流程组件与元件 线程组线程的执行方式Jmeter组件执行顺序 常见属性设置查看结果数的作用域举例 Jmeter参数化实现方式1.用户定义参数2.用户参数3.函数4.csv数据文件设置 每日复习 Jmeter基础 基本使用流程 启动项目案例 启动…...

图文并茂:解析Spring Boot Controller返回图片的三种方式

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 图文并茂&#xff1a;解析Spring Boot Controller返回图片的三种方式 前言使用Base64编码返回图片使用byte数组返回图片使用Resource对象返回图片图片格式转换与性能对比 前言 在互联网的世界里&…...

问题处理记录 | 表输出报错 Packet for query is too large (5,214,153 > 4,194,304).

这个错误是由于MySQL服务器接收到的查询数据包太大而引起的。具体来说&#xff0c;错误消息中提到的数据包大小为5,214,153字节&#xff0c;而MySQL服务器默认只接受最大为4,194,304字节的数据包。 要解决这个问题&#xff0c;你可以尝试通过修改MySQL服务器的配置来增大max_a…...

数据结构_栈和队列(Stack Queue)

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 栈&#xff1a; 代码&#xff1a;function/数据结构_栈/stack.c 钦某/c-language-learning - 码云 - 开源中国 (gitee.com)https://gitee.com/wang-qin928/c-language-learning/blob/master/function/…...

基于docker 的elasticsearch冷热分离及生命周期管理

文章目录 冷热集群架构的应用场景冷热集群架构的优势冷热集群架构实战搭建集群 索引生命周期管理认识索引生命周期索引生命周期管理的历史演变索引生命周期管理的基础知识Rollover&#xff1a;滚动索引 冷热集群架构的应用场景 某客户的线上业务场景如下&#xff1a;系统每天增…...

pikachu靶场(xss通关教程)

&#xff08;注&#xff1a;若复制注入代码攻击无效&#xff0c;请手动输入注入语句&#xff0c;在英文输入法下&#xff09; 反射型xss(get型) 1.打开网站 发现有个框&#xff0c;然后我们在框中输入一个“1”进行测试&#xff0c; 可以看到提交的数据在url处有显示&#xf…...

实验0.0 Visual Studio 2022安装指南

Visual Studio 2022 是一个功能强大的开发工具&#xff0c;对于计算机专业的学生来说&#xff0c;它不仅可以帮助你完成学业项目&#xff0c;还能为你将来的职业生涯打下坚实的基础。通过学习和使用 Visual Studio&#xff0c;你将能够更高效地开发软件&#xff0c;并在编程领域…...

数据结构之----线性表

线性表分为 顺序存储结构 和 链式存储结构 线性表的顺序存储结构&#xff1a; 线性表的顺序存储结构&#xff0c;指的是用一段地址连续的存储单元依次存储线性表的数据元素。 1&#xff0c;顺序表的结构&#xff1a; #define MAXSIZE 20 typedef int El…...