前后端交互的弯弯绕绕?前后端交互的方式ajax

前后端交互的弯弯绕绕前后端交互:
🆗,收拾一下心情让我们来聊一聊AJax吧,随着前端的飞速发展,前后的交互也发生了天翻地覆的变化:
前后端交互的方式有

前后端交互:

坐下来我们来谈谈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

(0)
CSDN's avatarCSDN
上一篇 2024年6月22日 下午12:24
下一篇 2024年6月22日 下午12:24

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注