如何通过 Axios 发送 multipart/form-data 请求?
时间: 2025-07-23 08:58:02 AIGC 浏览: 21
<think>我们使用Axios发送multipart/form-data请求时,需要创建一个FormData对象,并将需要发送的数据(包括文件)附加到该对象中。然后,在Axios配置中设置正确的Content-Type(通常由浏览器自动设置,但有时可能需要手动配置,但注意:对于FormData,浏览器会自动设置Content-Type为multipart/form-data并生成边界,所以通常我们不需要手动设置Content-Type头,否则可能会覆盖正确的边界信息)。
然而,在Node.js环境中,我们可能需要手动设置Content-Type头,并指定正确的边界。但在浏览器环境中,我们通常不设置Content-Type,让浏览器自动处理。
以下是在React中使用Axios发送multipart/form-data请求的示例:</think>### 通过 Axios 发送 multipart/form-data 请求
Axios 提供了便捷的方式处理 `multipart/form-data` 请求,以下是完整的实现方案:
#### 1. 基本实现代码
```jsx
import axios from 'axios';
import React, { useRef } from 'react';
const FileUploader = () => {
const fileInputRef = useRef(null);
const descriptionRef = useRef(null);
const handleSubmit = async (e) => {
e.preventDefault();
if (!fileInputRef.current.files.length) return;
// 创建 FormData 对象
const formData = new FormData();
formData.append('file', fileInputRef.current.files[0]); // 文件参数
formData.append('description', descriptionRef.current.value); // 文本参数
try {
// 发送 multipart/form-data 请求
const response = await axios.post('/api/upload', formData, {
headers: {
// Axios 会自动设置正确的 Content-Type
// 包括 multipart/form-data 和边界信息
'X-Custom-Header': 'value'
},
onUploadProgress: (progressEvent) => {
// 上传进度处理
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`${percentCompleted}% uploaded`);
}
});
console.log('上传成功:', response.data);
} catch (error) {
console.error('上传失败:', error.response?.data || error.message);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
ref={descriptionRef}
placeholder="文件描述"
/>
<input
type="file"
ref={fileInputRef}
accept=".jpg,.png,.pdf"
/>
<button type="submit">上传文件</button>
</form>
);
};
export default FileUploader;
```
#### 2. 关键代码解释
1. **FormData 对象**:
```javascript
const formData = new FormData();
formData.append('file', fileInputRef.current.files[0]);
formData.append('description', descriptionRef.current.value);
```
- 创建 FormData 实例,用于构建 multipart 请求体
- `append()` 方法添加文件和其他表单字段
2. **Axios POST 请求**:
```javascript
axios.post('/api/upload', formData, config)
```
- 第一个参数:API 端点 URL
- 第二个参数:FormData 对象作为请求体
- 第三个参数:配置对象(可选)
3. **自动处理 Content-Type**:
- Axios 检测到 FormData 对象时,会自动设置:
```
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123
```
- **不要手动设置 Content-Type**,否则会破坏边界信息
4. **上传进度监控**:
```javascript
onUploadProgress: (progressEvent) => {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
}
```
- `progressEvent.loaded`:已上传字节数
- `progressEvent.total`:文件总字节数
#### 3. 处理多个文件和复杂数据
```javascript
// 添加多个文件
const files = fileInputRef.current.files;
for (let i = 0; i < files.length; i++) {
formData.append(`files[${i}]`, files[i]);
}
// 添加嵌套对象数据
const metadata = {
user: { id: 123, name: 'John' },
tags: ['doc', 'important']
};
formData.append('metadata', JSON.stringify(metadata));
// 添加 Blob 数据
const blob = new Blob(['Hello world'], { type: 'text/plain' });
formData.append('textfile', blob, 'hello.txt');
```
#### 4. 服务端配置示例(Node.js/Express)
```javascript
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/api/upload', upload.single('file'), (req, res) => {
// 文件信息在 req.file
console.log('上传文件:', req.file);
// 其他字段在 req.body
console.log('描述:', req.body.description);
res.json({
status: 'success',
filename: req.file.originalname,
size: req.file.size
});
});
```
#### 5. 常见问题解决
1. **错误:`Request body larger than maxBodyLength`**
```javascript
// 解决方案:增加 maxBodyLength 配置
axios.post('/api/upload', formData, {
maxBodyLength: Infinity, // 取消请求体大小限制
maxContentLength: Infinity // 取消响应体大小限制
})
```
2. **错误:`Content-Type header missing boundary`**
- 原因:手动设置了 Content-Type
- 解决:删除手动设置的 Content-Type 头
3. **文件上传超时处理**
```javascript
axios.post('/api/upload', formData, {
timeout: 30000, // 30秒超时
onUploadProgress: (progressEvent) => {
// 更新进度状态
}
})
```
###
阅读全文
相关推荐



















