前后端交互:
坐下来我们来谈谈AJax。随着前端的快速发展,其前后的交互方式也发生了显着的变化。
前端和后端之间的交互方式有很多种,包括AJAX、表单提交、WebSocket 和RESTful API。
对于刚接触这个行业的朋友来说,这是很不厚道的。他们不知道要学什么,也不知道如何学。学习没用吗?
学习这篇文章:黑马前端AJAX入门实战
官方文档也极其详细,详细到不用看视频也能明白。
Axios 快速上手
Axios框架正式名称Ajax I/O 系统官方文档
虽然这不是一项新技术,但它本质上封装了原生的XMLHttpRequest,并被浏览器和Nodejs HTTP 客户端使用。
它基于Promises,Axios 提供了一种简洁而强大的异步请求发送方式,让开发者可以轻松发送:
axios的主要功能是GET、POST、PUT、DELETE等HTTP请求和处理响应。
浏览器和Node.js 支持:在不同环境下使用相同的API 基于Promise:使异步操作更加简洁请求取消:提供取消请求的方式客户端支持CSRF/XSRF 保护:跨站点请求防止伪造的安全功能转换请求和响应数据:自动将JSON 数据转换为JavaScript 对象。 拦截请求和响应:您可以在then 或catch 处理请求或响应之前拦截它们。
安装使用:
一般安装方法:
npm install:npm install axios 是框架使用的。如果本文不包含框架,则不会使用此方法。
通过cdn导入: script src=\’https://unpkg.com/axios/dist/axios.min.js\’/script
axios基本语法: 演示案例—— 查询国家省份接口:http://localhost:3000/area/provinceList
轴({
url: \’目标资源地址\’,
}).then(结果={
//对服务器返回的数据进行后续处理
})
!DOCTYPE html
html lang=\’en\’
头
元字符集=\’UTF-8\’
meta http-equiv=\’X-UA 兼容\’ content=\’IE=edge\’
元名称=\’视口\’内容=\’宽度=设备宽度,初始比例=1.0\’
titleAxiosDemo 使用:/title
/头
身体
!– 目标: 使用axios 库检索状态列表数据并将其显示在页面上–
!– 1.axios库介绍–
h1AxiosDemo使用:/h1
p 类=\’myp\’ /p
脚本src=\’https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js\’/script
脚本
//2.使用axios函数
轴({
url: \’http://localhost:3000/地区/都道府县列表\’
}).then(结果={
//将准备好的状态列表插入页面中
document.querySelector(\’.myp\’).innerHTML=result.data.provinceList.join(\’br\’)
})
/剧本
/身体
/html
为了方便测试,我简单定义了一个Node+Expresss+lowdb后端服务。获取地址:演示示例。
了解Node:Node 快速入门、Express 基本Deom、Express 高级升级
常用请求方法
上面演示了Axios 最基本的使用:无参数GET 请求并将结果渲染在页面上。
当然,我知道前端和后端如何交互有很多规则。 Axios 可以通过调整axios 实例上的各种配置来解决这个问题。
URL 请求路径方法接口请求类型标头设置请求标头。类型:Objectparams 请求参数。组合URL 上的参数。类型:Objectdata 请求参数。在请求正文中输入参数。类型:Objecttimeout 请求超时长度,单位为毫秒,类型:NumberbaseURL 请求的域名、基地址,类型:String
让我们仔细看看:
URL带参:
根据省份查询下属城市区域:GET请求,http://localhost:3000/area/cityList?province=江苏省
方法一:如上例,使用完整的URL并结合参数向URL发出请求,非常简单。
axios(\’http://localhost:3000/area/cityList?province=江苏省\’).then(result={
控制台.log(结果);
console.log(结果.数据);
})
方法二:
Method:设置接口的请求类型。常见请求类型:GET(默认)、POST、PUT、DELETE、PATCH,对应服务器执行的操作。
params:上面直接URL拼接可以满足请求,但是对于非固定参数值,固定URL无法满足场景。
params处理{key : value},结合URL请求url?key=value,方便前端操作和数据请求。
轴({
url:\’http://localhost:3000/地区/城市列表\’,
方法: ‘获取’,
params: {province:\’江苏\’ }
}).then(结果={
控制台.log(结果);
console.log(结果.数据);
})
路由命名:
路由命名:创建路由时为其分配唯一的名称。这允许您在代码中引用路由名称,而不是写出完整的URL 路径。
对于管理和维护大型应用程序的路由非常有用。如果需要更改路径,只需更新路由配置即可,而无需更改引用该路由的所有地方。
根据州|市查询街道县:GET请求,http://localhost:3000/area/district/:province/:city动态参数
查询江苏省和徐州市的区县:GET请求,http://localhost:3000/地区/区/江苏国会/徐州市
//路线命名:州|按城市查询街道县
const {省份, 城市}={ Province:\’江苏\’,city:\’徐州\’}
axios(`http://localhost:3000/地区/区/${县}/${城市}`).then(结果={
控制台.log(结果);
console.log(结果.数据);
})
JSON 数据:
JSON请求:为了方便程序开发时的数据传输,后端可以通过配置更方便地解析对象: application/json 用于请求标头。
用户注册请求:POST http://127.0.0.1:3000/users/register
请求JSON: {\’用户名\’: \’wsm\’,\’密码\’: \’000000\’}
data:属性中的信息包含在请求体中并发送给服务器。
//JSON数据请求:注册用户信息,POST请求JSON数据;
轴({
url:\’http://127.0.0.1:3000/用户/注册\’,
方法: ‘POST’,
数据: {
用户名: \’wsm\’,
密码:\’000000\’
}
}).then(结果={
控制台.log(结果);
console.log(结果.数据);
})
表单文件上传:
文件上传:使用FormData表单数据对象加载。
文件不再像以前那样是数字或字符串,因此通常需要将键值对的文件流放入FormData 中来传输数据。您可以查看请求体来了解请求体的结构。
身体
!– 文件选择元素–
输入类型=\’文件\’类=\’上传\’
img src=\’\’ alt=\’\’ class=\’my-img\’
脚本src=\’https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js\’/script
脚本
/*** 目标:上传图片并显示在网页上*/
//文件选择元素改变事件
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
轴({
url: \’http://127.0.0.1:3000/用户/userImg\’,
方法: ‘POST’,
数据: fd
}).then(结果={
控制台.log(结果)
//获取图片URL,添加img标签,加载并显示
const imgUrl=结果.data.imgUrl
document.querySelector(\’.my-img\’).src=imgUrl
})
})
/剧本
/身体
data:该属性支持直接发送FormData对象到后端服务器。
Axios 错误处理:
接口请求过程中难免会出现异常错误:根据响应状态码如何处理?
由于普通用户不会在控制台中读取错误消息,因此您需要编写代码来捕获错误并将其在页面上显示给用户。
使用axios catch 方法捕获此请求响应中的错误并进行进一步处理。具体错误处理流程如下:
如果请求成功,服务器返回状态码,但状态码超出了2xx范围,
Axios 捕获一个error.response 对象,其中包含响应数据、状态代码和标头信息。如果请求已成功发起但未收到响应,并且发送时出现问题,也会捕获error.request。 request ,例如请求配置错误。
开发人员可以使用.catch() 方法来处理这些错误。
演示用户注册请求:某些平台对用户名有自己的限制,并且会向同一用户显示错误消息。
POST http://127.0.0.1:3000/users/register 请求JSON: {\’userName\’: \’wsm\’,\’Password\’: \’000000\’}
//JSON数据请求:注册用户信息,POST请求JSON数据;
轴({
url:\’http://127.0.0.1:3000/用户/注册\’,
方法: ‘POST’,
数据: {
用户名: \’wsm\’,
密码:\’000000\’
}
}).then(结果={
警报(\’成功\’);
控制台.log(结果);
console.log(结果.数据);
}).catch(错误={
警报(\’失败\’);
控制台.log(错误);
})
AJax
Ajax 异步JavaScript 和XML:异步网络请求。 Ajax 允许您在不刷新页面的情况下请求数据。
旧的浏览器页面向服务器请求数据时,会返回整个页面的数据,强制页面刷新,不太人性化。
虽然你只需要更改页面上的部分数据,但服务器会发送整个页面的数据,这会消耗大量的网络资源。
发生异步网络请求是因为您只需要更改页面上的一些数据,但又不希望页面刷新。
Ajax的实现方式有很多种,包括原生的XMLHttpRequest、JQuery封装的Ajax、Axios等。
原生的XMLHttpRequest配置和调用方法非常繁琐,实现异步请求也非常繁琐。
jQuery ajax 比原生ajax 使用起来方便很多,但由于它使用的是ajax 异步网络请求,所以不需要引用jQuery 框架。
Axios 是一个基于Promise 的HTTP 客户端,适用于浏览器和Nodejs。这本质上是Promise 的实现版本。
我们建议在您的项目中使用Axios 库,因为它设计简单,API 简单,支持浏览器和Node,并且与各种前端框架集成良好。
学习XHR也是为了了解axios与服务器交互过程的真正原理。语法是:
//创建一个XMLHttpRequest 对象
const xhr=new XMLHttpRequest();
//配置请求
xhr.open(\’请求方法\’, \’请求网址\’);
//监控进程:的响应结果必须在请求之前声明。
xhr.addEventListener(\’loadend\’, ()={
console.log(xhr.response)
})
//发送请求
xhr.send();
XMLHttpRequest 对象:AJAX 的核心对象。提供使用JavaScript 发送HTTP 请求和接收HTTP 响应的功能。
配置请求:使用open方法配置请求的类型(如“GET”或“POST”)、URL以及是否异步。
发送请求:发送请求,使用send({})。参数是请求正文中包含的数据。
GET请求通过请求头发送数据,因此send参数必须设置为null。
处理服务器响应:通过侦听XMLHttpRequest 对象上的onreadystatechange 事件来处理服务器响应。
//当xhr对象发送或接收数据时,会经历五种状态:
//0 未初始化,未启动,1 已启动,open() 已调用,send() 尚未调用。
//2 发送状态,调用了send()但尚未收到响应,3 已接收,已收到一些响应数据
//4 完成,所有响应数据已收到并可在浏览器中使用
xhr.onreadystatechange=()={
if (xhr.readyState !==4) 返回值;
if (xhr.status=200 xhr.status 300 ){
console.log(xhr.responseText);
}
};
可以使用上述监视来执行响应处理。 当然这样比较麻烦,所以还有别的办法。将事件侦听器添加到XMLHttpRequest 对象。
用于监听loadend事件。 loadend 事件在请求结束时触发,无论请求成功还是失败。
常用请求方法:
URL带参:
查询参数原则的位置及语法:http://xxxx.com/xxx/xxx? 参数名1=值1 参数名2=值2
本机XHR 需要在URL 后携带查询参数字符串。如果不使用axios,可以将params参数连接到URL字符串的末尾。
//创建一个XMLHttpRequest 对象
const xhr=new XMLHttpRequest();
//配置请求
xhr.open(\’GET\’, \’http://localhost:3000/area/cityList?province=江苏\’);
//监听处理响应结果:
xhr.addEventListener(\’loadend\’, ()={
const data=JSON.parse(xhr.response); //解析响应内容
控制台.log(数据);
});
//发送请求
xhr.send();
多参数查询:
多个查询参数。自己组合比较麻烦。 URLSearchParams 将参数对象转换为格式为“参数名称=值参数名称=值”的字符串。
//1. 创建URLSearchParams 对象
const paramsObj=新URLSearchParams({
参数名称1:值1,
参数名称2: 值2
})
//2.生成指定格式的查询参数字符串
const queryString=paramsObj.toString()
//结果:参数名称1=值1 参数名称2=值2
升级上面的演示:
//创建一个XMLHttpRequest 对象
const xhr=new XMLHttpRequest();
//创建URLSearchParams 对象
const paramsObj=new URLSearchParams({province : \’江苏省\’ });
//配置请求
xhr.open(\’GET\’, `http://localhost:3000/area/cityList?${paramsObj.toString()}`); //请求参数组合;
//监听处理响应结果:
xhr.addEventListener(\’loadend\’, ()={
const data=JSON.parse(xhr.response); //解析响应内容
控制台.log(数据);
});
//发送请求
xhr.send();
JSON 请求数据:
原生AJax请求JSON数据:不如axios方便:
请求标头必须手动设置。 Content-Type: application/json 告诉服务器正在发送的内容类型是JSON 字符串。传递的请求体数据也是使用send({k:v; })方法发送;
const xhr=new XMLHttpRequest()
xhr.open(\’请求方法\’, \’请求网址\’)
xhr.addEventListener(\’loadend\’, ()={
console.log(xhr.response)
})
//1.告诉服务器你传递的内容类型是JSON字符串
xhr.setRequestHeader(\’内容类型\’, \’application/json\’)
//2.准备数据并将其转换为JSON字符串
const user={ 用户名: \’wsm\’, 密码: \’000000\’ }
const userStr=JSON.stringify(用户)
//3.发送请求体数据
xhr.send(userStr)
Promise
Promise 是一种异步编程解决方案。 Promise 表示异步操作的最终完成(或失败)及其结果值。
简单来说,Promise 是一个容器,用于存储未来将终止的事件(通常是异步操作)的结果。
Promise逻辑比较明显,是axios函数的内部工作机制,主要用来解决callback hell。
Promise 管理异步任务。语法是:
创建一个Promise 对象: new Promise; 构造函数同步运行,您可以在其中定义异步任务。
执行器函数采用执行器和函数作为参数。执行器函数有两个参数:resolve 和request。
用于在异步操作成功时兑现Promise,或在发生错误时拒绝Promise。
Promise.then方法是异步执行的,在执行器上执行resolve时会触发回调函数。
Promise.catch方法是异步执行的,执行器上执行reject时,支持链式编程,代码结构清晰。
//1.创建Promise对象
const p=new Promise((已解决,被拒绝)={
//2.执行异步任务并传递结果
//成功调用:solve(value)触发then()执行
//调用失败: Reject(value) 触发catch() 的执行
})
//3. 接收结果
p.then(结果={
//成功
}).catch(错误={
//失败
})
示例代码:使用Promises 通过在调用的函数之间切换并输出每个函数来管理异步任务。 then`catch`回调函数;
//1.创建Promise对象
const p=new Promise((已解决,被拒绝)={
//2. 执行异步代码
设置超时(()={
//solve(\’模拟AJAX请求-成功结果\’)
被拒绝(新错误(\’模拟AJAX请求的失败结果\’))
},2000)
})
//3. 获取结果
p.then(结果={
控制台.log(结果)
}).catch(错误={
控制台日志(错误)
})
致力于共同特征:
then():添加处理程序来处理Promise 的履行或拒绝catch():添加拒绝(操作失败)回调函数和Promisefinally():添加事件处理程序,无论Promise 对象的最终状态如何
都会被调用
Promise 的状态
Promise对象的状态是对异步操作的描述,Promise对象有三种状态:
待定(pending):这是Promise创建后的初始状态,在这个状态下,异步操作还没有完成,也没有失败
Promise对象将保持这个状态直到它被兑现(fulfilled)或被拒绝(rejected)
已兑现(fulfilled):当异步操作成功完成,并且Promise对象得到了一个值时,它就会转变为兑现状态
在这个状态下,我们可以通过then()方法设置的回调函数来获取这个值;
已拒绝(rejected):如果异步操作失败,或者在执行过程中抛出了一个错误,Promise对象就会变为拒绝状态
在这个状态下,我们可以通过then()方法或catch()方法设置的回调函数来处理这个错误;
但是如果程序上的错误,得通过catch()去拿到失败消息,在then()中是获取不了的;
//then 支持多参数,eroor函数处理异常结果;
promise.then(
value => { console.log(\’兑现:\’, value); },
error => { console.log(\’拒绝:\’, error); }
);
//catch 处理异常结果;
promise.catch(error=>{ console.log(\’拒绝:\’, error); });
三种状态:遇到resolve或者reject之前,都处于这个状态,且可以改变:
但如果确定了状态fulfilled/reject,则结果将永远不变,不能再次修改;
Promise 结合 XHR
使用Promise➕XHR请求省份列表: 模拟 axios 函数封装,更深入了解 axios 内部运作原理
需求:基于 Promise 和 XHR 封装 myAxios 函数,获取省份列表展示到页面:
function myAxios(config) {
return new Promise((resolve, reject) => {
// XHR 请求
// 调用成功/失败的处理程序
})
}
myAxios({
url: \’目标资源地址\’
}).then(result => {
}).catch(error => {
})
/* 目标:封装_简易axios函数_获取省份列表 */
// 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://localhost:3000/area/provinceList\’
}).then(result => {
console.log(result);
}).catch(error => {
console.log(error);
})
Axios回调地狱:
回调地狱 Callback Hell,有时也被称为**“金字塔厄运”:**Pyramid of Doom
指在 JavaScript 中使用回调函数嵌套过多、层级过深,导致代码难以理解、难以维护和可读性差的一种情况
这种情况通常出现在处理异步操作的场景,比如文件读取、数据库查询、网络请求等:
在回调地狱中,每个异步操作结果都依赖于前一个操作的完成,这就导致了大量的回调函数嵌套,形成了深层次的嵌套结构
Demo需求: 展示默认第一个省,第一个城市,第一个地区在下拉菜单中
因为: 查询地区接口需要,省份|城市参数,查询城市又需要省份参数,默认省份处于第一层所以: 在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱;
// 1. 获取默认第一个省份的名字
axios({url: \’http://localhost:3000/area/provinceList\’}).then(result => {
const province = result.data.provinceList[0]
document.querySelector(\’.province\’).innerHTML = province
// 2. 获取默认第一个城市的名字
axios({url: \’http://localhost:3000/area/cityList\’, params: { province }}).then(result => {
const city = result.data.cityList[0]
document.querySelector(\’.city\’).innerHTML = city
// 3. 获取默认第一个地区的名字
axios({url: `http://localhost:3000/area/district/${province}/${city}` }).then(result => {
console.log(result)
const areaName = result.data.district[0]
document.querySelector(\’.area\’).innerHTML = areaName
})
})
}).catch(error => {
console.dir(error)
})
Promise 链式解决回调地狱:
概念:依靠 then() 方法会返回一个新生成的 Promise 对象特性,继续串联下一环任务,直到结束
细节:then() 回调函数中的返回值,会影响新生成的 Promise 对象最终状态和结果
每个 Promise 对象中管理一个异步任务,用 then 返回 Promise 对象,串联起来
好处:通过链式调用,解决回调函数嵌套问题
/**
* 目标:把回调函数嵌套代码,改成Promise链式调用结构
* 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中
*/
let province = \’\’
// 1. 得到-获取省份Promise对象
axios({url: \’http://localhost:3000/area/provinceList\’}).then(result => {
province = result.data.provinceList[0]
document.querySelector(\’.province\’).innerHTML = province
// 2. 得到-获取城市Promise对象
return axios({ url: \’http://localhost:3000/area/cityList\’, params: { province }})
}).then(result => {
const city = result.data.cityList[0]
document.querySelector(\’.city\’).innerHTML = city
// 3. 得到-获取地区Promise对象
return axios({url: `http://localhost:3000/area/district/${province}/${city}` })
}).then(result => {
console.log(result)
const areaName = result.data.district[0]
document.querySelector(\’.area\’).innerHTML = areaName
})
async 函数和 await 解决回调地狱:
async 和 await 是 JavaScript 中用于简化异步编程的关键字
它们让你能够以一种更接近同步编程的方式来写异步代码,这样可以让代码更加清晰和易于维护:
Async: async 关键字用于声明一个异步函数,定义:函数声明、函数表达式前面;
当你在一个函数前面加上 async,这个函数就会返回一个 Promise 对象;如果函数正常执行结束,Promise 的状态将变为 fulfilled,并且返回值会作为 Promise的结果;如果函数抛出错误,Promise 的状态将变为 rejected,并且抛出的错误会作为 Promise 的结果;
Await: await 关键字用于等待一个 Promise 完成,且只能在 async 函数内部使用;
它会暂停 async 函数的执行,直到 Promise 的状态变为 fulfilled 或 rejected如果 Promise 成功解决,await 表达式的值就是 Promise 的结果如果 Promise 被拒绝,await 表达式会抛出拒绝的值
/* 目标:async和await_错误捕获 */
async function getData() {
// 1. try包裹可能产生错误的代码
try {
const pObj = await axios({ url: \’http://localhost:3000/area/provinceList\’ })
const province = pObj.data.provinceList[0]
const cObj = await axios({ url: \’http://localhost:3000/area/cityList\’, params: { province } })
const city = cObj.data.cityList[0]
const aObj = await axios({ url: `http://localhost:3000/area/district/${province}/${city}` })
const area = aObj.data.district[0]
document.querySelector(\’.province\’).innerHTML = province
document.querySelector(\’.city\’).innerHTML = city
document.querySelector(\’.area\’).innerHTML = area
} catch (error) {
// 2. 接着调用catch块,接收错误信息
console.dir(error)
}
}
getData();
Promise.all 静态方法
Promise.all() 方法用于将多个 Promise 实例,
包装成一个新的 Promise 实例: const p = Promise.all([p1,p2,p3]);
只有p1、p2、p3的状态都变成fulfilled:
p的状态才会变成fulfilled,p1、p2、p3的返回值组成一个数组,传递给p的回调函数;
只要p1、p2、p3之中有一个被rejected:
p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数;
let p1 = new Promise((resolve, reject) => {
resolve(\’成功了\’)
})
let p2 = new Promise((resolve, reject) => {
resolve(\’success\’)
})
let p3 = Promise.reject(\’失败\’)
Promise.all([p1, p2]).then((result) => {
console.log(result) //[\’成功了\’, \’success\’]
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 \’失败\’
})
本文章学习资源🔗:
黑马程序员前端AJAX入门到实战 ✅
Axios 3分钟让你学会axios在vue项目中的基本用法、Axios使用方法详解,从入门到进阶 当作进阶观看:
ajax与XHR的理解和使用
#以上关于前后端交互的弯弯绕绕的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91502.html