上传插件是 Strapi 管理面板中默认提供的媒体库插件的后端。使用管理面板中的媒体库或直接使用上传 API,您可以上传任何类型的文件以供 Strapi 应用程序使用。
默认情况下,Strapi 提供了一个 提供程序,用于将文件上传到本地目录,默认情况下,该目录在您的 Strapi 项目中为“public/uploads/”。如果您想将文件上传到其他位置,可以使用其他提供程序。
Strapi 维护的提供商包括:
配置
本节详细介绍了默认上传提供商的配置选项。如果使用其他提供商(例如 AWS S3 或 Cloudinary),请参阅该提供商文档中的可用配置参数。
本地服务器
默认情况下,Strapi 接受本地上传文件的 localServer
配置。这些将作为 koa-static 的选项传递。
您可以通过创建或编辑 ./config/plugins.js
文件来提供它们。以下示例设置了“max-age”标头。
module.exports = ({ env }) => ({
upload: {
config: {
providerOptions: {
localServer: {
maxage: 300000
},
},
},
},
})
最大文件大小
目前,负责解析请求的 Strapi 中间件需要配置为支持大于默认值 200MB 的文件大小,此外还需要将提供商选项传递给上传插件以设置 sizeLimit。
您可能还需要调整任何上游代理、负载平衡器或防火墙以允许更大的文件大小。
(例如 Nginx 有一个名为 client_max_body_size
的配置设置,由于其默认值仅为 1mb,因此需要进行调整。)
我们使用的库是 koa-body
,它使用 node-formidable
库来处理文件。
您可以通过在 ./config/middlewares.js
中的 body
中间件 配置中设置来直接将配置传递给中间件:
module.exports = [
// ...
{
name: 'strapi::body',
config: {
formLimit: '256mb', // modify form body
jsonLimit: '256mb', // modify JSON body
textLimit: '256mb', // modify text body
formidable: {
maxFileSize: 250 * 1024 * 1024, // multipart data, modify here limit of uploaded file size
},
},
},
// ...
]
除了中间件配置之外,你还可以在 ./config/plugins.js
中的插件配置中传递 sizeLimit
,它是一个以字节为单位的整数:
module.exports = {
// ...
upload: {
config: {
sizeLimit: 250 * 1024 * 1024 // 256mb in bytes
}
}
}
上传请求超时
默认情况下,strapi.server.httpServer.requestTimeout
的值设置为 330 秒。这包括上传。为了让网络连接较慢的用户能够上传大文件,可能需要增加此超时限制。建议的方法是设置 config/server.js|ts
文件中的 http.serverOptions.requestTimeout
参数(请参阅 服务器配置。
另一种方法是在 Strapi 启动前运行的 bootstrap
函数中设置 requestTimeout
值。这在需要以编程方式更改的情况下很有用 - 例如,暂时禁用并重新启用它:
module.exports = {
// ...
bootstrap({ strapi }) {
// Set the requestTimeout to 1,800,000 milliseconds (30 minutes):
strapi.server.httpServer.requestTimeout = 30 * 60 * 1000
},
}
响应式图像
在设置面板中启用“启用响应式友好上传”设置后,插件将生成以下响应式图像尺寸:
名称 | 最大尺寸 |
---|---|
大 | 1000px |
中 | 750px |
小 | 500px |
这些尺寸可以在 ./config/plugins.js
中覆盖:
module.exports = ({ env }) => ({
upload: {
config: {
breakpoints: {
xlarge: 1920,
large: 1000,
medium: 750,
small: 500,
xsmall: 64
},
},
},
})
断点更改仅适用于新图像,现有图像将不会调整大小或生成新尺寸。
Endpoints
方法 | 路径 | 描述 |
---|---|---|
GET | /api/upload/files | 获取文件列表 |
GET | /api/upload/files/:id | 获取特定文件 |
POST | /api/upload | 上传文件 |
POST | /api/upload?id=x | 更新文件信息 |
DELETE | /api/upload/files/:id | 删除文件 |
文件夹 是管理面板功能,不属于 REST 或 GraphQL API。通过 REST 或 GraphQL API 上传的文件位于自动创建的“API 上传”文件夹中。
示例
上传文件
将一个或多个文件上传到您的应用程序。
接受以下参数:
files
:要上传的文件。值可以是缓冲区或流。
<form>
<!-- Can be multiple files -->
<input type="file" name="files" />
<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。
上传条目文件
上传一个或多个将链接到特定条目的文件。
接受以下参数:
参数 | 描述 |
---|---|
files | 要上传的文件。值可以是缓冲区或流。 |
path (可选) | 将上传文件到的文件夹(仅支持 strapi-provider-upload-aws-s3)。 |
refId | 将链接到文件的条目的 ID。 |
ref | 将链接到文件的模型的唯一 ID (uid)(请参阅下文了解更多信息)。 |
source (可选) | 模型所在的插件的名称。 |
field | 将精确链接到文件的条目的字段。 |
例如,给定“Restaurant”模型属性:
{
// ...
"attributes": {
"name": {
"type": "string"
},
"cover": {
"type": "media",
"multiple": false
}
}
// ...
}
对应的代码是:
<form>
<!-- Can be multiple files if you setup "collection" instead of "model" -->
<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。
在创建条目时上传文件
您还可以在创建条目时添加文件。
例如,给定“Restaurant”模型属性:
{
// ...
"attributes": {
"name": {
"type": "string"
},
"cover": {
"type": "media",
"multiple": false
}
}
// ...
}
相应的代码为:
<form>
<!-- Can be multiple files if you setup "collection" instead of "model" -->
<input type="text" name="name" />
<input type="file" name="cover" />
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
const form = document.querySelector('form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const data = {};
const formData = new FormData();
form.elements
.forEach(({ name, type, value, files, ...element }) => {
if (!['submit', 'file'].includes(type)) {
data[name] = value;
} else if (type === 'file') {
files.forEach((file) => {
formData.append(`files.${name}`, file, file.name);
});
}
});
formData.append('data', JSON.stringify(data));
await fetch('/api/restaurants', {
method: 'post',
body: formData
});
});
</script>
您的输入数据必须包含在 data
键中,并且您需要 JSON.stringify
此对象。文件的键需要以 files
为前缀(例如,对于封面属性:files.cover
)。
如果您要为可重复组件上传文件,则必须使用以下语法指定要将文件添加到的项目的从零开始的索引:files.my_component_name[the_index].attribute_name
。例如,如果您放置了 3 个组件,并且文件用于第二个组件,则索引将为 1。
您必须在请求正文中发送 FormData。
模型定义
向模型(或另一个插件的模型)添加文件属性就像添加新关联一样。
在下面的第一个示例中,您将能够上传并将一个文件附加到头像属性。
{
"attributes": {
"pseudo": {
"type": "string",
"required": true
},
"email": {
"type": "email",
"required": true,
"unique": true
},
"avatar": {
"type": "media",
"multiple": false
}
}
}
在我们的第二个例子中,您可以上传并附加多张图片到餐厅。
{
"attributes": {
"name": {
"type": "string",
"required": true
},
"covers": {
"type": "media",
"multiple": true
}
}
}
更新 fileInfo
更新应用程序中的文件。
接受以下参数:
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,
})
从 API 控制器上传单个文件
从后端将文件添加到媒体库。
async create(ctx) {
// ...
const { body, files } = ctx.request;
const file = files["files.uploadedFile"];
const createdFiles = await strapi.plugins.upload.services.upload.upload({
data: {
fileInfo: {
name: "Name",
caption: "Caption",
alternativeText: "Alternative Text",
},
},
files: file,
});
// ...
},