一、axios 简介
axios 是一个基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js 环境,支持以下特性:
发送 HTTP 请求(GET/POST/PUT/DELETE 等)
拦截请求和响应
自动转换 JSON 数据
取消请求
并发请求处理
二、安装
-
使用 npm/yarn
npm install axios# 或yarn add axios
-
浏览器直接引入
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
三、基本用法
-
发送 GET 请求
axios.get('https://api.example.com/data') .then(response => { console.log(response.data); // 响应数据 }) .catch(error => { console.error('请求失败:', error); });
-
发送 POST 请求
axios.post('https://api.example.com/data', { name: 'John', age: 30 }) .then(response => { console.log(response.data); });
-
使用 async/await
async function fetchData() { try { const response = await axios.get('https://api.example.com/data'); console.log(response.data); } catch (error) { console.error(error); }}
四、请求配置
-
全局默认配置
axios.defaults.baseURL = 'https://api.example.com';axios.defaults.headers.common['Authorization'] = 'Bearer token123';axios.defaults.timeout = 5000; // 超时时间
-
单个请求配置
axios.get('/data', { params: { id: 1 }, // 查询参数 headers: { 'X-Custom-Header': 'value' }});
五、响应结构
响应对象包含以下字段:
{ data: {}, // 服务器返回的数据 status: 200, // HTTP 状态码 statusText: 'OK', headers: {}, // 响应头 config: {}, // 请求配置 request: {} // 原始的 XMLHttpRequest 对象(浏览器)}
六、错误处理
-
通用错误捕获
axios.get('/data') .catch(error => { if (error.response) { // 服务器返回了非 2xx 状态码 console.log(error.response.status); console.log(error.response.data); } else if (error.request) { // 请求已发送但无响应 console.log('No response received'); } else { // 请求配置错误 console.log('Error:', error.message); } });
-
全局错误拦截
axios.interceptors.response.use( response => response, error => { // 统一处理错误 return Promise.reject(error); });
七、高级功能
-
并发请求
const request1 = axios.get('/data1');const request2 = axios.get('/data2');axios.all([request1, request2]) .then(axios.spread((res1, res2) => { console.log(res1.data, res2.data); }));
-
取消请求
const source = axios.CancelToken.source();axios.get('/data', { cancelToken: source.token}).catch(thrown => { if (axios.isCancel(thrown)) { console.log('请求被取消:', thrown.message); }});// 取消请求source.cancel('用户取消操作');
-
请求拦截器
axios.interceptors.request.use( config => { // 在发送请求前做些什么(如添加 token) config.headers.Authorization = 'Bearer token'; return config; }, error => { return Promise.reject(error); });
八、常见场景示例
-
上传文件
const formData = new FormData();formData.append('file', fileInput.files[0]);axios.post('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' }});
-
下载文件
axios.get('/download', { responseType: 'blob' }) .then(response => { const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', 'file.pdf'); document.body.appendChild(link); link.click(); });
九、最佳实践
封装 axios:创建 api.js 统一管理接口
环境区分:通过 .env 文件配置不同环境的 baseURL
安全防护:结合 CSRF Token 或 JWT 进行身份验证
性能优化:合理设置超时时间,使用缓存策略
示例:
以下是使用 Axios 和 Spring Boot 实现前后端分离的登录功能的步骤详解:
- 后端实现(Spring Boot)
1.1 添加依赖
在 pom.xml 中添加必要依赖:
<!-- Spring Web --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><!-- 数据库(以 JPA + H2 为例) --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope></dependency><!-- 密码加密 --><dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId></dependency>
1.2 配置数据库和加密
在 application.properties 中配置:
spring.datasource.url=jdbc:h2:mem:testdbspring.datasource.driverClassName=org.h2.Driverspring.h2.console.enabled=truespring.jpa.hibernate.ddl-auto=update
1.3 创建用户实体类
@Entitypublic class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true) private String username; private String password; // Getters and Setters}
1.4 创建 Repository
public interface UserRepository extends JpaRepository<User, Long> { User findByUsername(String username);}
1.5 创建 Service 层
@Servicepublic class AuthService { @Autowired private UserRepository userRepository; @Autowired private BCryptPasswordEncoder passwordEncoder; public boolean authenticate(String username, String password) { User user = userRepository.findByUsername(username); return user != null && passwordEncoder.matches(password, user.getPassword()); }}
1.6 创建 Controller
@RestController@RequestMapping("/api/auth")@CrossOrigin(origins = "http://localhost:3000") // 允许前端跨域请求public class AuthController { @Autowired private AuthService authService; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) { boolean isValid = authService.authenticate( loginRequest.getUsername(), loginRequest.getPassword() ); if (isValid) { return ResponseEntity.ok().body("登录成功"); } else { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误"); } }}// 登录请求DTOpublic class LoginRequest { private String username; private String password; // Getters and Setters}
- 前端实现(使用 Axios)
2.1 安装 Axios
npm install axios
2.2 登录组件示例(React)
import React, { useState } from 'react';import axios from 'axios';const LoginForm = () => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post( 'http://localhost:8080/api/auth/login', { username, password }, { headers: { 'Content-Type': 'application/json' } } ); if (response.status === 200) { alert('登录成功'); // 跳转到主页或处理登录状态 } } catch (err) { if (err.response && err.response.status === 401) { setError('用户名或密码错误'); } else { setError('登录失败,请重试'); } } }; return ( <form onSubmit={handleSubmit}> <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="用户名" /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="密码" /> {error && <div className="error">{error}</div>} <button type="submit">登录</button> </form> );};export default LoginForm;
- 测试流程
启动 Spring Boot 应用:
mvn spring-boot:run
启动前端应用:
npm start
在登录页面输入用户名和密码,验证是否返回正确响应。