Files
filecodebox/docs/guide/upload.md
T

421 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 文件上传
FileCodeBox 提供了多种灵活的文件上传方式,支持普通上传和分片上传,满足不同场景的需求。
## 上传方式
FileCodeBox 支持以下几种上传方式:
### 拖拽上传
将文件直接拖拽到上传区域即可开始上传。这是最便捷的上传方式。
1. 打开 FileCodeBox 首页
2. 将文件从文件管理器拖拽到上传区域
3. 松开鼠标,文件开始上传
4. 上传完成后获取提取码
::: tip 提示
拖拽上传支持同时拖拽多个文件(取决于主题支持)。
:::
### 点击上传
点击上传区域,通过系统文件选择器选择文件。
1. 点击上传区域的「选择文件」按钮
2. 在弹出的文件选择器中选择要上传的文件
3. 确认选择后文件开始上传
4. 上传完成后获取提取码
### 粘贴上传
支持从剪贴板直接粘贴图片进行上传(部分主题支持)。
1. 复制图片到剪贴板(截图或复制图片)
2. 在上传区域使用 `Ctrl+V`Windows/Linux)或 `Cmd+V`macOS)粘贴
3. 图片自动开始上传
4. 上传完成后获取提取码
::: warning 注意
粘贴上传仅支持图片格式,不支持其他文件类型。具体支持情况取决于所使用的主题。
:::
## 文件大小限制
### 默认限制
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `uploadSize` | 10MB | 单文件最大上传大小 |
### 修改上传限制
管理员可以通过管理面板或配置文件修改上传大小限制:
```python
# 设置最大上传大小为 100MB
uploadSize = 104857600 # 100 * 1024 * 1024
```
::: info 说明
`uploadSize` 的单位是字节。常用换算:
- 10MB = 10485760
- 50MB = 52428800
- 100MB = 104857600
- 500MB = 524288000
- 1GB = 1073741824
:::
### 超出限制的处理
当上传文件超过大小限制时,系统会返回 403 错误:
```json
{
"detail": "大小超过限制,最大为10.00 MB"
}
```
## 普通上传 API
### 文件上传接口
**POST** `/share/file/`
Content-Type: `multipart/form-data`
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `file` | file | 是 | 要上传的文件 |
| `expire_value` | int | 否 | 过期数值,默认 1 |
| `expire_style` | string | 否 | 过期方式,默认 `day` |
**过期方式选项:**
| 值 | 说明 |
|----|------|
| `day` | 按天过期 |
| `hour` | 按小时过期 |
| `minute` | 按分钟过期 |
| `forever` | 永不过期 |
| `count` | 按下载次数过期 |
**响应示例:**
```json
{
"code": 200,
"detail": {
"code": "654321",
"name": "example.pdf"
}
}
```
**cURL 示例:**
```bash
# 上传文件(默认1天有效期)
curl -X POST "http://localhost:12345/share/file/" \
-F "file=@/path/to/file.pdf"
# 上传文件并指定有效期(7天)
curl -X POST "http://localhost:12345/share/file/" \
-F "file=@/path/to/file.pdf" \
-F "expire_value=7" \
-F "expire_style=day"
# 上传文件并指定有效期(可下载10次)
curl -X POST "http://localhost:12345/share/file/" \
-F "file=@/path/to/file.pdf" \
-F "expire_value=10" \
-F "expire_style=count"
# 分享文本
curl -X POST "http://localhost:12345/share/text/" \
-F "text=这是要分享的文本内容"
# 通过取件码下载文件
curl -L "http://localhost:12345/share/select/?code=取件码" -o downloaded_file
```
::: tip 需要认证时
如果管理面板关闭了游客上传(`openUpload=0`),需要先登录获取 token
```bash
# 1. 登录获取 token
curl -X POST "http://localhost:12345/admin/login" \
-H "Content-Type: application/json" \
-d '{"password": "FileCodeBox2023"}'
# 返回: {"code":200,"msg":"success","detail":{"token":"xxx.xxx.xxx","token_type":"Bearer"}}
# 2. 使用 token 上传文件
curl -X POST "http://localhost:12345/share/file/" \
-H "Authorization: Bearer xxx.xxx.xxx" \
-F "file=@/path/to/file.pdf"
# 3. 使用 token 分享文本
curl -X POST "http://localhost:12345/share/text/" \
-H "Authorization: Bearer xxx.xxx.xxx" \
-F "text=这是要分享的文本内容"
```
:::
## 分片上传 API
对于大文件,FileCodeBox 支持分片上传功能。分片上传将大文件分割成多个小块分别上传,支持断点续传。
::: warning 前提条件
分片上传功能需要管理员启用:`enableChunk=1`
:::
### 分片上传流程
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 初始化上传 │ ──▶ │ 上传分片 │ ──▶ │ 完成上传 │
│ /init/ │ │ /chunk/ │ │ /complete/ │
└─────────────┘ └─────────────┘ └─────────────┘
┌───────────┐
│ 循环上传 │
│ 每个分片 │
└───────────┘
```
### 1. 初始化上传
**POST** `/chunk/upload/init/`
**请求参数:**
```json
{
"file_name": "large_file.zip",
"file_size": 104857600,
"chunk_size": 5242880,
"file_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
```
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `file_name` | string | 是 | - | 文件名 |
| `file_size` | int | 是 | - | 文件总大小(字节) |
| `chunk_size` | int | 否 | 5MB | 分片大小(字节) |
| `file_hash` | string | 是 | - | 文件的 SHA256 哈希值 |
**响应示例:**
```json
{
"code": 200,
"detail": {
"existed": false,
"upload_id": "abc123def456789",
"chunk_size": 5242880,
"total_chunks": 20,
"uploaded_chunks": []
}
}
```
| 字段 | 说明 |
|------|------|
| `existed` | 文件是否已存在(秒传) |
| `upload_id` | 上传会话 ID |
| `chunk_size` | 分片大小 |
| `total_chunks` | 总分片数 |
| `uploaded_chunks` | 已上传的分片索引列表 |
### 2. 上传分片
**POST** `/chunk/upload/chunk/{upload_id}/{chunk_index}`
**路径参数:**
| 参数 | 说明 |
|------|------|
| `upload_id` | 初始化时返回的上传会话 ID |
| `chunk_index` | 分片索引,从 0 开始 |
**请求体:**
Content-Type: `multipart/form-data`
| 参数 | 类型 | 说明 |
|------|------|------|
| `chunk` | file | 分片数据 |
**响应示例:**
```json
{
"code": 200,
"detail": {
"chunk_hash": "a1b2c3d4e5f6..."
}
}
```
**cURL 示例:**
```bash
# 上传第一个分片(索引为 0
curl -X POST "http://localhost:12345/chunk/upload/chunk/abc123def456789/0" \
-F "chunk=@/path/to/chunk_0"
```
### 3. 完成上传
**POST** `/chunk/upload/complete/{upload_id}`
**路径参数:**
| 参数 | 说明 |
|------|------|
| `upload_id` | 上传会话 ID |
**请求参数:**
```json
{
"expire_value": 7,
"expire_style": "day"
}
```
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `expire_value` | int | 是 | 过期数值 |
| `expire_style` | string | 是 | 过期方式 |
**响应示例:**
```json
{
"code": 200,
"detail": {
"code": "789012",
"name": "large_file.zip"
}
}
```
### 断点续传
分片上传支持断点续传。当上传中断后:
1. 使用相同的 `file_hash` 重新调用初始化接口
2. 服务器返回 `uploaded_chunks` 列表,包含已上传的分片索引
3. 客户端只需上传不在列表中的分片
4. 所有分片上传完成后调用完成接口
**示例流程:**
```javascript
// 1. 初始化上传
const initResponse = await fetch('/chunk/upload/init/', {
method: 'POST',
body: JSON.stringify({
file_name: 'large_file.zip',
file_size: fileSize,
chunk_size: 5 * 1024 * 1024,
file_hash: fileHash
})
});
const { upload_id, uploaded_chunks, total_chunks } = await initResponse.json();
// 2. 上传未完成的分片
for (let i = 0; i < total_chunks; i++) {
if (!uploaded_chunks.includes(i)) {
const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
await fetch(`/chunk/upload/chunk/${upload_id}/${i}`, {
method: 'POST',
body: chunk
});
}
}
// 3. 完成上传
await fetch(`/chunk/upload/complete/${upload_id}`, {
method: 'POST',
body: JSON.stringify({
expire_value: 7,
expire_style: 'day'
})
});
```
## 错误处理
### 常见错误
| HTTP 状态码 | 错误信息 | 原因 | 解决方案 |
|-------------|----------|------|----------|
| 403 | 大小超过限制 | 文件超过 `uploadSize` 限制 | 减小文件大小或联系管理员调整限制 |
| 403 | 上传频率限制 | 超过 IP 上传频率限制 | 等待限制时间窗口后重试 |
| 400 | 过期时间类型错误 | `expire_style` 值不在允许列表中 | 使用有效的过期方式 |
| 404 | 上传会话不存在 | `upload_id` 无效或已过期 | 重新初始化上传 |
| 400 | 无效的分片索引 | `chunk_index` 超出范围 | 检查分片索引是否正确 |
| 400 | 分片不完整 | 完成上传时分片数量不足 | 确保所有分片都已上传 |
### 频率限制
系统对上传操作有频率限制,防止滥用:
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `uploadMinute` | 1 | 限制时间窗口(分钟) |
| `uploadCount` | 10 | 时间窗口内最大上传次数 |
当超过频率限制时,需要等待时间窗口过后才能继续上传。
### 错误响应格式
```json
{
"detail": "错误信息描述"
}
```
## 上传配置
### 相关配置项
| 配置项 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| `openUpload` | int | 1 | 是否开放上传(1=开放,0=关闭) |
| `uploadSize` | int | 10485760 | 最大上传大小(字节) |
| `enableChunk` | int | 0 | 是否启用分片上传(1=启用,0=禁用) |
| `uploadMinute` | int | 1 | 上传频率限制时间窗口(分钟) |
| `uploadCount` | int | 10 | 时间窗口内最大上传次数 |
| `expireStyle` | list | ["day","hour","minute","forever","count"] | 允许的过期方式 |
### 配置示例
```python
# 允许上传 100MB 文件,启用分片上传
uploadSize = 104857600
enableChunk = 1
# 放宽上传频率限制:每 5 分钟最多 50 次
uploadMinute = 5
uploadCount = 50
# 只允许按天和按次数过期
expireStyle = ["day", "count"]
```
## 下一步
- [文件分享](/guide/share) - 了解完整的分享流程
- [配置说明](/guide/configuration) - 了解所有配置选项
- [存储配置](/guide/storage) - 了解文件存储方式
- [安全设置](/guide/security) - 了解安全相关配置