什么是Axios
Axios 是一个基于 Promise 的 HTTP 客户端,用于在浏览器和 后端 中发送异步的 HTTP 请求。它功能强大、易用,常用于与 API 交互,发送 GET、POST、PUT、DELETE 等请求。
Axios 的主要特点:
-
支持 Promise
Axios 基于 Promise,能够很好地与现代 JavaScript 异步编程模式结合使用,例如使用 async/await,简化了异步代码的编写。 -
请求和响应的拦截器
通过使用拦截器,开发者可以在请求发出前或响应返回后对数据进行处理,这使得在请求发送前进行一些处理或对返回结果进行统一的预处理变得更容易。 -
自动转换 JSON 数据
Axios 会自动将响应中的 JSON 数据转换为 JavaScript 对象,这使得处理数据变得简单。 -
浏览器支持防止 CSRF
在浏览器环境中,Axios 自动为跨站请求伪造(CSRF)防护提供默认支持,这使得它在处理安全性时非常有用。 -
客户端支持取消请求
通过 CancelToken,你可以随时取消正在进行的请求,以节省资源或优化用户体验。 -
支持超时和防止重复请求
Axios 支持为请求设置超时,并且可以轻松处理需要避免重复发送请求的场景。 -
在 Node.js 中支持流
在 Node.js 环境中,Axios 支持与文件流进行交互,这在处理大文件下载或上传时非常方便。
关于promise,可以移步看我这篇帖子:
https://blog.csdn.net/qq_55018264/article/details/142874115
Axios的基础使用
Axios 基于 Promise,意味着你可以像处理 Promise 一样使用它的 then() 和 catch() 方法。then() 用于处理成功的请求,catch() 用于处理失败的请求
基本的 GET 请求示例:
const axios = require('axios');
// 发送 GET 请求
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});
POST 请求的例子:
axios.post('https://api.example.com/data', {
username: 'test',
password: '1234'
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});
也可以使用 async/await,它是 Promise 的简化语法:
async function fetchData() {
try {
const response = await axios.get('/api/data');
console.log(response.data);
} catch (error) {
console.error(error);
}
}
以spring boot+vue3为例学习使用(简易版)
代码(便于读者测试):
实体类 Article
package com.accumulation.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Article {
private int id; // 新增 id 属性
private String title;
private String category;
private String time;
private String state;
}
控制器 TodoController
package com.accumulation.controller;
import com.accumulation.pojo.Article;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/article")
@CrossOrigin//支持跨域
public class ArticleController {
private List<Article> articleList = new ArrayList<>();
{
articleList.add(new Article(1,"特斯拉市值一夜蒸发超4700亿", "时事", "2024-10-10", "已发布"));
articleList.add(new Article(2,"中国男足为何在澳大利亚一败涂地", "足球", "2024-10-11", "草稿"));
articleList.add(new Article(3,"博物馆文创为何让年轻人着迷", "旅游", "2024-10-10", "已发布"));
}
//新增文章
@PostMapping("/add")
public String add(@RequestBody Article article) {
articleList.add(article);
return "新增成功";
}
//获取所有文章信息
@GetMapping("/getAll")
public List<Article> getAll(HttpServletResponse response) {
return articleList;
}
//根据文章分类和发布状态搜索
@GetMapping("/search")
public List<Article> search(@RequestParam(required = false) String category, @RequestParam(required = false) String state) {
return articleList.stream().filter(article -> {
boolean matchesCategory = (category == null || category.isEmpty() || article.getCategory().contains(category));
boolean matchesState = (state == null || state.isEmpty() || article.getState().contains(state));
return matchesCategory && matchesState;
}).collect(Collectors.toList());
}
// 根据ID删除文章
@GetMapping("/del")
public String del(@RequestParam int id) {
articleList.removeIf(a -> a.getId() == id); // 根据 ID 删除文章
return "删除成功";
}
// 更新文章标题
@PostMapping("/update")
public String update(@RequestBody Article article) {
for (int i = 0; i < articleList.size(); i++) {
if (articleList.get(i).getId() == article.getId()) {
articleList.get(i).setTitle(article.getTitle()); // 更新标题
break;
}
}
return "更新成功";
}
}
Vue 组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
文章分类: <input type="text" v-model="searchConditions.category">
发布状态: <input type="text" v-model="searchConditions.state">
<button v-on:click="search">搜索</button>
<br />
<br />
<!-- 文章列表 -->
<table border="1 solid" colspa="0" cellspacing="0">
<tr>
<th>文章标题</th>
<th>分类</th>
<th>发表时间</th>
<th>状态</th>
<th>操作</th>
</tr>
<tr v-for="(article, index) in articleList" :key="article.id">
<td>{{ article.title }}</td>
<td>{{ article.category }}</td>
<td>{{ article.time }}</td>
<td>{{ article.state }}</td>
<td>
<button v-on:click="edit(index)">编辑</button>
<button v-on:click="del(index)">删除</button>
</td>
</tr>
</table>
<!-- 编辑文章模态框 -->
<div v-if="isEditing" class="modal">
<h2>编辑文章</h2>
<label>标题:</label>
<input type="text" v-model="currentArticle.title">
<br />
<button v-on:click="updateArticle">保存</button>
<button v-on:click="cancelEdit">取消</button>
</div>
</div>
<!-- 导入axios的js文件 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="module">
// 导入vue模块
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
// 创建vue应用实例
createApp({
data() {
return {
articleList: [],
searchConditions: {
category: '',
state: ''
},
isEditing: false, // 控制模态框的显示与隐藏
currentArticle: {} // 当前编辑的文章
}
},
methods: {
search: function() {
//发送请求,完成搜索,携带搜索条件
axios.get('http://localhost:8080/article/search', {
params: {
category: this.searchConditions.category,
state: this.searchConditions.state
}
})
.then(result => {
//成功回调 result.data
//把得到的数据赋值给articleList
this.articleList = result.data;
})
.catch(err => {
console.log(err);
});
},
edit(index) {
// 获取当前编辑的文章
this.currentArticle = { ...this.articleList[index] }; // 复制当前文章数据
this.isEditing = true; // 显示编辑模态框
},
del(index) {
const article = this.articleList[index];
axios.get('http://localhost:8080/article/del?id=' + article.id)
.then(result => {
console.log(result.data);
this.refreshArticles();
}).catch(err => {
console.log(err);
});
},
updateArticle() {
// 发送更新请求
axios.post('http://localhost:8080/article/update', this.currentArticle)
.then(result => {
console.log(result.data); // 打印更新成功的消息
this.refreshArticles(); // 刷新文章列表
this.cancelEdit(); // 关闭模态框
}).catch(err => {
console.log(err);
});
},
cancelEdit() {
this.isEditing = false; // 隐藏编辑模态框
this.currentArticle = {}; // 清空当前文章
},
refreshArticles() {
axios.get('http://localhost:8080/article/getAll')
.then(result => {
this.articleList = result.data;
}).catch(err => {
console.log(err);
});
}
},
mounted() {
this.refreshArticles(); // 初始化时获取所有文章数据
}
}).mount('#app');
</script>
</body>
</html>
实现情况(搜索、编辑、删除)
前后端分析:
后端(Spring Boot):
@RestController:标识该类为 RESTful 控制器,返回的对象会自动序列化为 JSON 格式。
@RequestMapping(“/article”):定义请求的基础路径。
@CrossOrigin:允许跨域请求,这对于前后端分离的应用非常重要。
@RequestBody 注解将请求体中的 JSON 数据映射到 Article 对象。
后端的 Spring Boot 应用会接收到来自前端的请求。根据请求的 URL,Spring 会调用相应的处理方法。
对于获取所有文章的请求,调用 getAll() 方法,返回 articleList
返回的数据会被 Spring 自动转换为 JSON 格式并发送回前端。
前端(Vue 3 + Axios):
data() 中定义了 articleList 和 searchConditions。
search 方法通过 Axios 发送 GET 请求以获取符合条件的文章,并将结果赋值给 articleList。这个请求会向后端发送一个带有查询参数的 HTTP GET 请求,获取符合条件的文章数据。
mounted 钩子函数在组件加载时获取所有文章数据,发送 GET 请求以获取所有文章数据,这个请求会触发浏览器向后端服务器发送一个 HTTP GET 请求,要求获取所有文章的信息