一、axios 简介
axios 是一个基于 Promise 的 HTTP 客户端,可用于浏览器和 Node.js 环境,支持以下特性:
发送 HTTP 请求(GET/POST/PUT/DELETE 等)
拦截请求和响应
自动转换 JSON 数据
取消请求
并发请求处理
二、安装
1. 使用 npm/yarn
npm install axios
# 或
yarn add axios
2. 浏览器直接引入
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
三、基本用法
1. 发送 GET 请求
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data); // 响应数据
})
.catch(error => {
console.error('请求失败:', error);
});
2. 发送 POST 请求
axios.post('https://api.example.com/data', {
name: 'John',
age: 30
})
.then(response => {
console.log(response.data);
});
3. 使用 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);
}
}
四、请求配置
1. 全局默认配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = 'Bearer token123';
axios.defaults.timeout = 5000; // 超时时间
2. 单个请求配置
axios.get('/data', {
params: { id: 1 }, // 查询参数
headers: { 'X-Custom-Header': 'value' }
});
五、响应结构
响应对象包含以下字段:
{
data: {}, // 服务器返回的数据
status: 200, // HTTP 状态码
statusText: 'OK',
headers: {}, // 响应头
config: {}, // 请求配置
request: {} // 原始的 XMLHttpRequest 对象(浏览器)
}
六、错误处理
1. 通用错误捕获
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);
}
});
2. 全局错误拦截
axios.interceptors.response.use(
response => response,
error => {
// 统一处理错误
return Promise.reject(error);
}
);
七、高级功能
1. 并发请求
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);
}));
2. 取消请求
const source = axios.CancelToken.source();
axios.get('/data', {
cancelToken: source.token
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('请求被取消:', thrown.message);
}
});
// 取消请求
source.cancel('用户取消操作');
3. 请求拦截器
axios.interceptors.request.use(
config => {
// 在发送请求前做些什么(如添加 token)
config.headers.Authorization = 'Bearer token';
return config;
},
error => {
return Promise.reject(error);
}
);
八、常见场景示例
1. 上传文件
const formData = new FormData();
formData.append('file', fileInput.files[0]);
axios.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
2. 下载文件
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 实现前后端分离的登录功能的步骤详解:
1. 后端实现(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:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
1.3 创建用户实体类
@Entity
public 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 层
@Service
public 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("用户名或密码错误");
}
}
}
// 登录请求DTO
public class LoginRequest {
private String username;
private String password;
// Getters and Setters
}
2. 前端实现(使用 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;
3. 测试流程
启动 Spring Boot 应用:
mvn spring-boot:run
启动前端应用:
npm start
在登录页面输入用户名和密码,验证是否返回正确响应。