使用axios及和spirng boot 交互

Axios

Axios是一个基于PromiseHTTP,可以发送getpost等请求,它作用于浏览器Node.js中。当运行在浏览器时,使用XMLHttpRequest接口发送请求;当运行在Node.js时,使用HTTP对象发送请求。

使用步骤:

  第一步:安装axios  略

第二步:在项目中使用Axios时,通常的做法是先将Axios封装成一个模块,然后在组件中导入模块。

第三步:编写各种请求 这里只说明 基本的get请求post请求

request({url: '请求路径',method: 'get',params: { 参数 }
}).then(res => {console.log(res)
}).catch(error => {console.log(error)
})

get请求:

/*** 发送GET请求*/
export const getReq = (url, params) => {return axios({method: 'get',params, // 使用params而非dataurl: `${base}${url}`,headers: {'token': localStorage.getItem("token"),}});
}

 使用它:

// 获取用户列表,带分页参数
getReq('/api/users', { page: 1, pageSize: 10 }).then(res => {console.log('用户列表:', res.data);}).catch(err => {console.error('请求失败:', err);});

 post请求:

request({url: '请求路径',method: 'post',data: { 参数 }
}).then(res => {console.log(res)
}).catch(error => {console.log(error)
})

export const postReq = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,headers: {'token': localStorage.getItem("token"),}});

  

 异步请求调用中 async+await 的应用

代码:

export const fetchData = async (url, params) => {try {const response = await axios({method: 'get',params, // 修正:使用 params 而非 dataurl: `${base}${url}`,headers: {'token': localStorage.getItem('token'),}});return response.data;} catch (error) {console.error('请求失败:', error);throw error; // 修正:重新抛出错误,让调用者处理}
};

 async+await 的概念

async/await 是一种建立在Promise之上的编写异步或非阻塞代码的新方法。async 是异步的意思,而 await 是 async wait的简写,即异步等待。

所以从语义上就很好理解 async 用于声明一个 函数 是异步的,而await 用于等待一个异步方法执行完成。

那么想要同步使用数据的话,就可以使用 async+await 。

 说明:async函数返回的是一个 Promise 对象。async 函数(包含函数语句、函数表达式、Lambda表达式)会返回一个 Promise 对象,如果在函数中  一个直接量,async 会把这个直接量通过promise.solve() 封装成 Promise 对象。

如果 async 函数没有返回值, 它会返回 promise.solve(underfined)。

await 等待的是一个表达式,这个表达式的计算结果是 Promise 对象或者其它值(换句话说,await 可以等任意表达式的结果)。

如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。

如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

调用方式:

Promise 链式调用:.then().catch() 同步风格的

await:在 async 函数内部使用

  • romise 链式调用适合 “非阻塞、并行、兼容旧环境” 的场景,强调异步操作的独立性。
  • async/await适合 “顺序依赖、复杂流程、高可读性” 的场景,让异步代码更接近同步思维模式。
1. 使用 .then() 和 .catch() 链式调用
import { fetchData } from './api'; // 假设从 api.js 导入// 调用 fetchData 获取用户列表
fetchData('/api/users', { page: 1, pageSize: 10 }).then(data => {console.log('用户列表:', data);// 处理返回的数据(如更新组件状态)}).catch(error => {console.error('请求失败:', error);// 显示错误消息(如弹框提示)});
//其他逻辑会和fetchData同步进行
.....  

2. 在 async 函数内部使用 await

async function loadUsers() {try {// 等待请求完成并获取数据const data = await fetchData('/api/users', { page: 1, pageSize: 10 });console.log('用户列表:', data);// 可以直接使用同步风格的代码处理数据const firstUser = data.list[0];console.log('第一个用户:', firstUser);} catch (error) {console.error('请求失败:', error);// 错误处理逻辑}
}// 调用 async 函数
loadUsers();

当执行 loadUsers() 函数时,它会返回一个 Promise 对象,并且其内部逻辑会以异步方式执行。以下是详细解释:

1. 函数返回值:Promise 对象
  • 原因:任何使用 async 关键字声明的函数都会自动返回一个 Promise。

  • 示例验证

    javascript

    const result = loadUsers();
    console.log(result instanceof Promise); // 输出: true
    
  • Promise 的状态

    • 成功(fulfilled):当 fetchData 请求成功且没有抛出异常时,Promise 会 resolve,并传递 loadUsers 函数的返回值(若没有显式返回,默认返回 undefined)。
    • 失败(rejected):当 fetchData 抛出异常,或 loadUsers 内部 try 块中的代码报错时,Promise 会 reject,并传递错误对象。
2. 函数执行流程(异步本质)

javascript

console.log('开始执行');
loadUsers();
console.log('结束执行');// 输出顺序:
// 开始执行
// 结束执行
// (等待 fetchData 请求完成后)
// 用户列表: ...
// 第一个用户: ...

  • 关键特点
    1. loadUsers() 函数被调用后立即返回 Promise,不会阻塞后续代码执行。
    2. await fetchData(...) 仅暂停函数内部的执行,不会影响外部代码(如 console.log('结束执行') 会先于 fetchData 的结果输出)。
    3. 当 fetchData 的 Promise 解决(成功 / 失败)时,loadUsers 内部的 await 会恢复执行,并决定 Promise 的最终状态。
3. Promise 的解决(resolve)情况

当 fetchData 请求成功且 try 块内代码无异常时:

  • loadUsers 的 Promise 会 resolve,返回值为 undefined(因为函数没有显式 return)。

  • 等价于:

    javascript

    async function loadUsers() {// ... 代码 ...return undefined; // 隐式返回
    }
    
  • 可通过 .then() 捕获结果

    javascript

    loadUsers().then(result => {console.log('loadUsers 返回值:', result); // 输出: undefined
    });
    
4. Promise 的拒绝(reject)情况

当出现以下情况时,loadUsers 的 Promise 会 reject:

  1. fetchData 抛出错误

    javascript

    fetchData('/api/users', { page: 1 }).catch(error => {throw new Error('请求失败: ' + error); // 被 loadUsers 的 catch 捕获});
    
  2. try 块内其他代码报错

    javascript

    const firstUser = data.list[0]; // 若 data.list 为 undefined,会抛出 TypeError
    
  3. catch 块中重新抛出错误

    javascript

    catch (error) {console.error('请求失败:', error);throw error; // 重新抛出,导致 Promise reject
    }
    

  • 可通过 .catch() 捕获错误

    javascript

    loadUsers().catch(error => {console.error('loadUsers 错误:', error);
    });
    
5. 与 Promise 链式调用的等价关系

loadUsers 函数的异步逻辑等价于以下 Promise 写法:

javascript

function loadUsers() {return fetchData('/api/users', { page: 1, pageSize: 10 }).then(data => {console.log('用户列表:', data);const firstUser = data.list[0];console.log('第一个用户:', firstUser);// 隐式返回 undefined}).catch(error => {console.error('请求失败:', error);throw error; // 重新抛出错误,保持 Promise 链的异常传递});
}
6. 如何获取函数的执行结果?
(1)使用 .then()

javascript

loadUsers().then(() => {console.log('数据处理完成');}).catch(error => {console.error('处理失败:', error);});
(2)在另一个 async 函数中使用 await

javascript

async function processData() {try {await loadUsers(); // 等待 loadUsers 的 Promise 解决console.log('loadUsers 执行完毕');} catch (error) {console.error('processData 捕获到错误:', error);}
}

  • 返回值loadUsers() 始终返回一个 Promise 对象。
  • 状态由内部逻辑决定
    • 成功时(fetchData 正常返回且无代码错误):Promise resolve,返回 undefined
    • 失败时(fetchData 报错或代码异常):Promise reject,传递错误对象。
  • 异步本质:函数内部使用 await 暂仅停自身执行,不阻塞主线程,整体仍为异步操作。

应用transformRequest

export const postRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,transformRequest: [function (data) {let ret = '';for (let key in data) {ret += encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + '&';}return ret;}],headers: {'Content-Type': 'application/x-www-form-urlencoded', // 修正为表单格式}});
}

说明:

  1. 数据格式与请求头的关系

    • application/json:请求体应为 JSON 格式(如{"key": "value"})。
    • application/x-www-form-urlencoded:请求体应为表单格式(如key=value&key2=value2)。
  2. transformRequest的影响

    • 当前代码将对象转换为表单格式数据,但请求头却声明为 JSON,导致后端可能无法解析。
    • 若后端期望 JSON 数据,应移除transformRequest并保持application/json头。
  3. 正确的搭配方式

    数据格式Content-Type是否需要 transformRequest
    JSONapplication/json不需要
    表单数据application/x-www-form-urlencoded需要(如当前函数)
    二进制文件 / 表单multipart/form-data不需要

函数调用示例

场景 1:提交表单数据到后端

import { postRequest } from './api.js'; // 导入函数// 表单数据
const formData = {username: 'test_user',password: '123456',email: 'test@example.com'
};// 调用函数
postRequest('/api/register', formData).then(response => {console.log('注册成功:', response.data);}).catch(error => {console.error('注册失败:', error);});
场景 2:发送 JSON 数据(需修改函数)

如果需要发送 JSON 数据,应使用以下封装:

export const postJsonRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,headers: {'Content-Type': 'application/json',}});
}// 调用示例
const userData = {name: '张三',age: 25,hobbies: ['阅读', '编程']
};postJsonRequest('/api/users', userData).then(res => console.log(res.data));

调用注意事项

  1. 参数说明

    • url:API 路径(如/api/login),会自动拼接base(如http://localhost:8080)。
    • params:需要发送的数据对象,会被transformRequest转换为表单格式。
  2. 错误处理

    • 在调用时添加.catch()处理请求失败:

      postRequest(...).catch(error => {const status = error.response?.status || '网络错误';const message = error.response?.data?.message || '请求失败';console.error(`状态码 ${status}: ${message}`);
      });
      
  3. 与其他请求函数的区别

    • 若后端接口需要不同的 Content-Type,应创建不同的封装函数(如 JSON 格式、文件上传等)。

  1. 数据为对象格式(如{key: value}
  2. 后端接口期望表单数据(application/x-www-form-urlencoded
  3. 添加错误处理逻辑以应对请求失败的情况

如果需要发送 JSON 数据,最好创建专门的函数,不需要transformRequest

对不同格式的数据,spring boot 端的处理:

场景推荐注解示例
处理 JSON 数据@RequestBody@RequestBody User user
处理简单表单数据(少量参数)@RequestParam@RequestParam("username") String name
处理复杂表单数据(对象绑定)@ModelAttribute@ModelAttribute User user
同时支持 JSON 和表单(需自定义)@RequestBody + 转换器配置 FormHttpMessageConverter

建议:

  • JSON:统一使用 @RequestBody,前端发送 application/json
  • 表单:使用 @RequestParam 或 @ModelAttribute,前端发送 application/x-www-form-urlencoded
  • 避免混用:不要试图用 @RequestBody 同时处理两种格式,会增加复杂度。

postJsonRequest 

export const postJsonRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,  // axios 自动将对象序列化为 JSONheaders: {'Content-Type': 'application/json',}});
}

 调用方式例子:

// 发送用户数据
const userData = {username: 'john',email: 'john@example.com',isActive: true
};postJsonRequest('/api/users', userData).then(res => console.log('用户创建成功:', res.data)).catch(err => console.error('错误:', err));

发送表单数据(application/x-www-form-urlencoded)

export const postFormRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,transformRequest: [function (data) {let ret = '';for (let key in data) {ret += encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + '&';}return ret;}],headers: {'Content-Type': 'application/x-www-form-urlencoded',}});
}

  调用方式例子:

// 提交登录表单
const loginData = {username: 'admin',password: '123456',rememberMe: true
};postFormRequest('/api/login', loginData).then(res => {localStorage.setItem('token', res.data.token);console.log('登录成功');}).catch(err => alert('登录失败: ' + err.message));

比与适用场景及编码问题

方案Content-Type数据格式后端适配前端写法
方案一(JSON)application/json{"key":"value"}Spring Boot 的 @RequestBody直接传递对象
方案二(表单)application/x-www-form-urlencodedkey=value&key2=value2Spring Boot 的 @RequestParam/@ModelAttribute需手动或用库序列化
  1. 后端接口匹配

    • JSON 格式:确保后端使用 @RequestBody 注解
    • 表单格式:确保后端使用 @RequestParam 或 @ModelAttribute
  2. 编码问题

    • 表单数据中的特殊字符(如中文)会被 encodeURIComponent 自动编码
    • JSON 数据中的中文会被序列化为 Unicode 字符(如 \u4e2d

putRequest :

export const putRequest = (url, params) => {return axios({method: 'put',url: `${base}${url}`,data: params,transformRequest: [function (data) {if (!data) return '';const ret = [];for (let key in data) {if (data.hasOwnProperty(key)) {const value = data[key];// 处理值为 null 或 undefined 的情况const encodedValue = value === null || value === undefined ? '' : encodeURIComponent(value);ret.push(`${encodeURIComponent(key)}=${encodedValue}`);}}// 使用 join 避免末尾多余的 &return ret.join('&');}],headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).catch(error => {console.error('PUT 请求失败:', error);// 可以在这里进行统一的错误处理throw error; // 继续抛出错误,让调用者可以捕获});
};

参考vue+element UI 学习总结笔记(一)_vue+elementui一点-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85397.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

布局文件的逐行详细解读

总览 源码 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto&…

VTK 显示大量点云数据及交互(点云拾取、着色、测量等)功能

VTK (Visualization Toolkit) 是一个强大的开源可视化库&#xff0c;非常适合处理点云数据。下面将介绍如何使用 VTK 显示大量点云数据&#xff0c;并实现点云拾取、着色、测量等功能。 基本点云显示 创建一个基本的点云显示程序&#xff1a; cpp #include <vtkSmartPoi…

性能优化 - 高级进阶: 性能优化全方位总结

文章目录 Pre1. 概述&#xff1a;性能优化提纲与使用场景2. 准备阶段2.1 明确优化范围与目标2.2 环境与工具准备 3. 数据收集与指标确认3.1 关键资源维度与指标项3.2 监控体系搭建与初始采集3.3 日志与追踪配置 4. 问题定位思路4.1 从整体到局部的分析流程4.2 常见瓶颈维度检查…

Mybatis之Integer类型字段为0,入库为null

背景&#xff1a; 由于项目某个功能用到优先级字段来判断&#xff0c;需要在mysql表中定义一个字段XX&#xff0c;类型为int&#xff0c;默认为0&#xff0c;具体值由后台配置&#xff0c;正常入库即可 问题&#xff1a; 由于后台配置存量其他类型的数据无需该字段&#xff0c…

上海市计算机学会竞赛平台2022年3月月赛丙组洗牌

题目描述 给定一个整数 nn&#xff0c;表示 nn 张牌&#xff0c;牌的编号为 11 到 nn。 再给定一个洗牌置换 f1,f2,…,fnf1​,f2​,…,fn​&#xff0c;进行一次洗牌操作时&#xff0c;应将第一号位置的牌交换到第 f1f1​ 号位置&#xff0c;将第 ii 号位置的牌交换到第 fifi…

DINO-R1:激励推理能力的视觉基础模型

摘要 近期&#xff0c;人们对大型语言模型&#xff08;如DeepSeek-R1&#xff09;推理能力的关注呈爆炸式增长&#xff0c;通过基于强化学习的微调框架&#xff08;如组相对策略优化&#xff08;Group Relative Policy Optimization&#xff0c;GRPO&#xff09;方法&#xff…

Linux--LVM逻辑卷扩容

Linux–LVM逻辑卷扩容 文章目录 Linux--LVM逻辑卷扩容📚 LVM 常用命令分类及基本格式✅ 1. 物理卷(PV)相关命令✅ 2. 卷组(VG)相关命令✅ 3. 逻辑卷(LV)相关命令🔍 三、查看类命令简写说明使用命令及基本格式:lvm逻辑卷扩容步骤:1.添加硬盘设备2.检测新增硬盘 添加…

C#基础语法与控制台操作

1. 控制台操作基础 控制台程序是学习C#的起点。以下是一些常用的控制台操作方法&#xff1a; 1.1. 清除控制台 Console.Clear(); // 清除控制台内容1.2. 输出字符串 Console.WriteLine("Hello World!"); // 在屏幕的当前位置换行输出字符串 Console.Write("…

100.Complex[]同时储存实数和虚数两组double的数组 C#例子

在信号处理中&#xff0c;IQ 数据&#xff08;In-phase and Quadrature&#xff09;通常表示复数形式的信号&#xff0c;其中实部表示同相分量&#xff0c;虚部表示正交分量。Complex[] data 是一个包含 IQ 数据的数组&#xff0c;每个元素是一个复数&#xff0c;表示一个信号样…

停止追逐 React 重渲染

大多数开发者都在浪费时间对抗多余的重渲染。真正的 React 架构师根本让问题无从产生——下面就来揭开他们的思路&#xff0c;以及为何大多数所谓的性能优化技巧反而拖慢了你的应用。 重渲染的无尽轮回 先来直击痛点&#xff1a;如果还在项目里到处撒 useMemo、useCallback&…

流水线的安全与合规 - 构建可信的交付链

流水线的安全与合规 - 构建可信的交付链 “安全左移 (Shift-Left Security)”的理念 “安全左移”是 DevSecOps 的核心理念,指的是将安全测试和考量,从软件开发生命周期 (SDLC) 的末端(发布前),尽可能地向左移动到更早的阶段(如编码、构建、测试阶段)。 为何对 SRE 至…

​​​​​​​神经网络基础讲解 一

​​一.神经网络 ​ ​​1. 全连接神经网络&#xff08;Fully Connected Network, FCN&#xff09;​​ ​​核心概念&#xff1a;​​ ​​输入层​​&#xff1a;接收原始数据&#xff08;如数字、图片像素等&#xff09; 数字矩阵 。​​隐藏层​​&#xff1a;对数据…

MySQL 8.0 OCP 英文题库解析(二十二)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题201~210 试题2…

【大模型推理】PD分离场景下decoder负载均衡,如何选取decoder

https://mp.weixin.qq.com/s?__bizMzg4NTczNzg2OA&mid2247507420&idx1&sn4b32726abd205c7f94144bcb9105330f&chksmce64b9fc7f1d8de04a40b0153302dee52262c6f104c67195e2586e75c8093b8be493f252c8a3#rd 在非 Local 场景下&#xff0c;Prefill 定时获取 Decode …

【IP地址】IP应用场景的使用方向

网络安全领域 通过IP地址查询&#xff0c;安全系统能够实时监控网络流量&#xff0c;识别异常访问行为。例如&#xff0c;当某个IP地址在短时间内频繁发起大量请求&#xff0c;且访问模式与正常用户存在明显差异时&#xff0c;系统可将其标记为可疑IP&#xff0c;触发风险预警…

3-18 WPS JS宏 颜色设置实例应用(按条件设置单元格颜色)学习笔记

前面讲解了关于单元格的一些格式的设置&#xff0c;本节课再讲解一下各种清除方法。 1.函数解析与用法 Range().clear()//清除全部 Range().Value2null //清除内容 Range().ClearContents()//清除内容 Range().ClearFormats()//清除格式 Range().EntireRow.Range()//以Ra…

从零开始的云计算生活——第二十天,脚踏实地,SSH与Rsync服务

目录 一.故事背景 二.SSH带外管理 1.概述 2. 配置文件 3.命令解析 4.登录方式配置 a.用户名密码登录 b.公钥验证登录 5.实操生成密钥对 三.Rsyncsersync实现数据实时同步 1.rsync概述 2.rsync运行原理 3.rsync部署 4.备份测试 配置备份目录 5.rsyncsersync 实现…

SpringAI + DeepSeek大模型应用开发 - 初识篇

一、认识AI 1. AI的发展 AI&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;使机器能像人类一样思考、学习和解决问题的技术。 2. 大模型及其原理 在自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;中&#xff0c;…

c++第八天-多态

虚函数虚析构函数纯虚函数与抽象类 多态实现的条件&#xff1a;&#xff08;1&#xff09;公有继承 &#xff08;2&#xff09;派生类重写基类虚函数 &#xff08;3&#xff09;基类指针/引用指向派生类对象 虚函数不能是构造函数&#xff0c;不能是静态函数&#xff0c;不能…

全景图渲染Vue3+TS使用Photo Sphere Viewer插件实现

1.Photo Sphere Viewer插件安装: title=插件安装 体验AI代码助手 代码解读复制代码npm install photo-sphere-viewer -S 或 yarn add photo-sphere-viewer -S 2.原始全景图展示 初始化标签容器 体验AI代码助手 代码解读复制代码 // 全景图的根节点必须要具备宽高 TS引用,创建…