REST API:上传文件
🌐 REST API: Upload files
Page summary:
/api/uploadREST API 端点使你能够将文件上传到媒体库,获取分页文件列表,更新文件元数据,以及从你的 Strapi 应用中删除文件。🌐 The
/api/uploadREST API endpoints enable you to upload files to the Media Library, retrieve paginated file lists, update file metadata, and delete files from your Strapi application.
媒体库功能 在 Strapi 的后端服务器中由 upload 包提供支持。要向 Strapi 上传文件,你可以直接从管理面板使用媒体库,也可以使用 REST API,可用的端点如下:
🌐 The Media Library feature is powered in the back-end server of Strapi by the upload package. To upload files to Strapi, you can either use the Media Library directly from the admin panel, or use the REST API, with the following available endpoints :
| 方法 | 路径 | 描述 |
|---|---|---|
| GET | /api/upload/files | 获取文件列表 |
| GET | /api/upload/files/page | 获取分页文件列表 |
| GET | /api/upload/files/:id | 获取特定文件 |
| POST | /api/upload | 上传文件 |
| POST | /api/upload?id=x | 更新文件信息 |
| DELETE | /api/upload/files/:id | 删除文件 |
- 文件夹 是仅限管理员面板的功能,不属于内容 API(REST 或 GraphQL)。通过 REST 上传的文件位于自动创建的“API 上传”文件夹中。
- GraphQL API 不支持上传媒体文件。要上传文件,请使用 REST API 或直接从管理面板的 媒体库 添加文件。一些用于更新或删除已上传媒体文件的 GraphQL 变更仍然可能(详情请参见 GraphQL API 文档)。
获取文件列表
🌐 Get a list of files
2 个端点从媒体库返回文件:/api/upload/files 将每个文件作为平铺数组返回,而 /api/upload/files/page 使用标准分页响应返回文件。对于任何非简单的媒体库,请使用 /api/upload/files/page。
获取所有文件
🌐 Get all files
GET /api/upload/files 返回媒体库中所有文件的扁平数组:
[
{
"id": 1,
"documentId": "a1b2c3...",
"name": "photo.jpg",
"url": "/uploads/photo.jpg",
"mime": "image/jpeg",
"size": 12.34
// ...other file fields
}
// ...
]
此端点会忽略分页参数,并始终返回所有文件。对于大型媒体库,响应可能会非常大,因此建议使用 /api/upload/files/page。
🌐 This endpoint ignores pagination parameters and always returns every file. For large media libraries the response can be very large, so prefer /api/upload/files/page instead.
获取分页文件列表
🌐 Get a paginated list of files
GET /api/upload/files/page 使用标准的 分页响应 返回文件,封装在 data 数组和 meta.pagination 对象中。
它接受与其他 REST 集合端点相同的查询参数:
🌐 It accepts the same query parameters as other REST collection endpoints:
| 参数 | 描述 |
|---|---|
pagination[page] | 页码(以1为起 始)。默认 1。 |
pagination[pageSize] | 每页文件数量。默认使用 api.rest.defaultLimit 配置 (25),如果设置了 api.rest.maxLimit 则上限为其值。 |
pagination[start] | 基于偏移的分页:要跳过的文件数量。 |
pagination[limit] | 基于偏移的分页:返回的最大文件数量。 |
pagination[withCount] | 是否运行计数查询并在响应中包含 total 和 pageCount。默认值为 true。 |
filters | 对结果进行 过滤。 |
sort | 对结果进行 排序。 |
fields | 选择 要返回的字段。 |
populate | 填充 关联关系。 |
分页参数使用嵌套格式(pagination[page]=2&pagination[pageSize]=10),而不是扁平格式(page=2&pageSize=10)。按页分页(page/pageSize)和按偏移分页(start/limit)是互斥的:将它们结合使用会返回 400 错误。有关两种分页方法的详细信息,请参见 排序与分页。
🌐 Pagination parameters use the nested format (pagination[page]=2&pagination[pageSize]=10), not the flat format (page=2&pageSize=10). Pagination by page (page/pageSize) and pagination by offset (start/limit) are mutually exclusive: combining them returns a 400 error. For details on both pagination methods, see Sort & Pagination.
GET /api/upload/files/page?pagination[page]=2&pagination[pageSize]=10
{
"data": [
{
"id": 1,
"documentId": "a1b2c3...",
"name": "photo.jpg",
"url": "/uploads/photo.jpg",
"mime": "image/jpeg",
"size": 12.34
// ...other file fields
}
],
"meta": {
"pagination": {
"page": 2,
"pageSize": 10,
"pageCount": 4,
"total": 100
}
}
}
在使用偏移分页时,meta.pagination 对象返回 start 和 limit,而不是 page 和 pageSize:
🌐 When using pagination by offset, the meta.pagination object returns start and limit instead of page and pageSize:
GET /api/upload/files/page?pagination[start]=20&pagination[limit]=5&pagination[withCount]=false&filters[mime][$startsWith]=image/
{
"data": [
// ...
],
"meta": {
"pagination": {
"start": 20,
"limit": 5
}
}
}
当 pagination[withCount] 是 false 时,计数查询将被跳过,并且 total 和 pageCount 将从响应中省略。
🌐 When pagination[withCount] is false, the count query is skipped and total and pageCount are omitted from the response.
上传文件
🌐 Upload files
将一个或多个文件上传到你的应用。
🌐 Upload one or more files to your application.
files 是唯一接受的参数,用于描述要上传的文件。其值可以是 Buffer 或 Stream。
在使用 AWS S3 并将 ACL 参数设置为 "private" 时,上传端点返回的文件 URL 会自动生成签名。签名 URL 包含 X-Amz-Signature 查询参数和响应中的 isUrlSigned: true 标志,使其即使在私有桶 ACL 下也可访问。签名 URL 的过期时间基于你的 signedUrlExpires 配置(默认:15 分钟)。
🌐 When using AWS S3 with the ACL parameter set to "private", file URLs returned by the upload endpoints are automatically signed. Signed URLs include X-Amz-Signature query parameters and an isUrlSigned: true flag in the response, making them accessible despite the private bucket ACL. Signed URLs expire based on your signedUrlExpires configuration (default: 15 minutes).
上传图片时,包含一个 fileInfo 对象以设置文件名、替代文本和标题。
🌐 When uploading an image, include a fileInfo object to set the file name, alt text, and caption.
- Browser
- Node.js
<form>
<input type="file" name="files" />
<input
type="hidden"
name="fileInfo"
value='{"name":"homepage-hero","alternativeText":"Person smiling while
holding laptop","caption":"Hero image used on the homepage"}'
/>
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
const form = document.querySelector('form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
await fetch('/api/upload', {
method: 'post',
body: new FormData(e.target)
});
});
</script>
import { FormData } from 'formdata-node';
import fetch, { blobFrom } from 'node-fetch';
const file = await blobFrom('./1.png', 'image/png');
const form = new FormData();
form.append('files', file, "1.png");
form.append(
'fileInfo',
JSON.stringify({
name: 'Homepage hero',
alternativeText: 'Person smiling while holding laptop',
caption: 'Hero image used on the homepage',
})
);
const response = await fetch('http://localhost:1337/api/upload', {
method: 'post',
body: form,
});
你必须在请求正文中发送 FormData。
🌐 You have to send FormData in your request body.
上传入口文件
🌐 Upload entry files
上传一 个或多个将链接到特定条目的文件。
🌐 Upload one or more files that will be linked to a specific entry.
接受以下参数:
🌐 The following parameters are accepted:
| 参数 | 描述 |
|---|---|
files | 要上传的文件。值可以是 Buffer 或 Stream。 |
path (可选) | 文件将上传到的文件夹(仅在 strapi-provider-upload-aws-s3 上支持)。 |
refId | 将与文件关联的条目 ID。 |
ref | 文件将关联的模型的唯一 ID(uid)(详见下文)。 |
source (可选) | 模型所在插件的名称。 |
field | 文件将精确关联到的条目字段。 |
例如,给定 Restaurant 模型属性:
🌐 For example, given the Restaurant model attributes:
{
// ...
"attributes": {
"name": {
"type": "string"
},
"cover": {
"type": "media",
"multiple": false,
}
}
// ...
}
以下是相应前端的示例代码:
🌐 The following is an example of a corresponding front-end code:
<form>
<input type="file" name="files" />
<input type="text" name="ref" value="api::restaurant.restaurant" />
<input type="text" name="refId" value="5c126648c7415f0c0ef1bccd" />
<input type="text" name="field" value="cover" />
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
const form = document.querySelector('form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
await fetch('/api/upload', {
method: 'post',
body: new FormData(e.target)
});
});
</script>
你必须在请求正文中发送 FormData。
🌐 You have to send FormData in your request body.
更新文件信息
🌐 Update fileInfo
更新应用中的文件。
🌐 Update a file in your application.
fileInfo 是唯一被接受的参数,用于描述要更新的文件信息:
import { FormData } from 'formdata-node';
import fetch from 'node-fetch';
const fileId = 50;
const newFileData = {
alternativeText: 'My new alternative text for this image!',
};
const form = new FormData();
form.append('fileInfo', JSON.stringify(newFileData));
const response = await fetch(`http://localhost:1337/api/upload?id=${fileId}`, {
method: 'post',
body: form,
});
模型定义
🌐 Models definition
向模型(或另一个插件的模型 )添加文件属性就像添加一个新的关联。
🌐 Adding a file attribute to a model (or the model of another plugin) is like adding a new association.
以下示例允许你上传并附加一个文件到 avatar 属性:
🌐 The following example lets you upload and attach one file to the avatar attribute:
{
// ...
{
"attributes": {
"pseudo": {
"type": "string",
"required": true
},
"email": {
"type": "email",
"required": true,
"unique": true
},
"avatar": {
"type": "media",
"multiple": false,
}
}
}
// ...
}
以下示例允许你上传并附加多张图片到 restaurant 内容类型:
🌐 The following example lets you upload and attach multiple pictures to the restaurant content-type:
{
// ...
{
"attributes": {
"name": {
"type": "string",
"required": true
},
"covers": {
"type": "media",
"multiple": true,
}
}
}
// ...
}