中间件配置
¥Middlewares configuration
在 Strapi 中,3 个中间件概念共存:
¥In Strapi, 3 middleware concepts coexist:
整个 Strapi 服务器应用的全局中间件是 配置并启用。这些中间件可以应用于应用级别或 API 级别。
当前文档描述了如何实现它们。
插件还可以添加全局中间件(参见 服务器 API 文档)。¥Global middlewares are configured and enabled for the entire Strapi server application. These middlewares can be applied at the application level or at the API level.
The present documentation describes how to implement them.
Plugins can also add global middlewares (see Server API documentation).路由中间件的范围更有限,并且在路由级别被配置和用作中间件。它们在 路由文档 中进行了描述。
¥Route middlewares have a more limited scope and are configured and used as middlewares at the route level. They are described in the routes documentation.
文档服务中间件适用于文档服务 API,并具有自己的 implementation 和相关的 生命周期钩子。
¥Document Service middlewares apply to the Document Service API and have their own implementation and related lifecycle hooks.
./config/middlewares.js
文件用于定义 Strapi 服务器应应用的所有全局中间件。
¥The ./config/middlewares.js
file is used to define all the global middlewares that should be applied by the Strapi server.
仅应用 ./config/middlewares.js
中存在的中间件。加载中间件发生在特定的 加载订单 中,每个中间件都有一些 命名约定 和 可选配置。
¥Only the middlewares present in ./config/middlewares.js
are applied. Loading middlewares happens in a specific loading order, with some naming conventions and an optional configuration for each middleware.
Strapi 使用内置的内部中间件预填充 ./config/middlewares.js
文件,这些中间件都有自己的 配置选项。
¥Strapi pre-populates the ./config/middlewares.js
file with built-in, internal middlewares that all have their own configuration options.
加载顺序
¥Loading order
./config/middlewares.js
文件导出一个数组,其中顺序很重要,并控制中间件堆栈的执行顺序:
¥The ./config/middlewares.js
file exports an array, where order matters and controls the execution order of the middleware stack:
- JavaScript
- TypeScript
module.exports = [
// The array is pre-populated with internal, built-in middlewares, prefixed by `strapi::`
'strapi::logger',
'strapi::errors',
'strapi::security',
'strapi::cors',
// custom middleware that does not require any configuration
'global::my-custom-node-module',
// custom name to find a package or a path
{
name: 'my-custom-node-module',
config: {
foo: 'bar',
},
},
// custom resolve to find a package or a path
{
resolve: '../some-dir/custom-middleware',
config: {
foo: 'bar',
},
},
// custom configuration for internal middleware
{
name: 'strapi::poweredBy',
config: {
poweredBy: 'Some awesome company',
},
},
// remaining internal & built-in middlewares
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
];
export default [
// The array is pre-populated with internal, built-in middlewares, prefixed by `strapi::`
'strapi::logger',
'strapi::cors',
'strapi::body',
'strapi::errors',
// ...
'my-custom-node-module', // custom middleware that does not require any configuration
{
// custom name to find a package or a path
name: 'my-custom-node-module',
config: {
foo: 'bar',
},
},
{
// custom resolve to find a package or a path
resolve: '../some-dir/custom-middleware',
config: {
foo: 'bar',
},
},
];
如果你不确定将中间件放置在堆栈中的位置,请将其添加到列表的末尾。
¥If you aren't sure where to place a middleware in the stack, add it to the end of the list.
命名约定
¥Naming conventions
全局中间件根据其来源可以分为不同类型,定义了以下命名约定:
¥Global middlewares can be classified into different types depending on their origin, which defines the following naming conventions:
中间件类型 | 起源 | 命名约定 |
---|---|---|
内部的 | 内置中间件(即包含在 Strapi 中),自动加载 | strapi::middleware-name |
应用层 | 从 ./src/middlewares 文件夹加载 | global::middleware-name |
API 级 | 从 ./src/api/[api-name]/middlewares 文件夹加载 | api::api-name.middleware-name |
插入 | 从 strapi-server.js 导出到 插件接口的 middlewares 属性 | plugin::plugin-name.middleware-name |
外部的 | 可以是:
| - 由于它们是直接从配置文件中配置和解析的,因此没有命名约定。 |
可选配置
¥Optional configuration
中间件可以有一个带有以下参数的可选配置:
¥Middlewares can have an optional configuration with the following parameters:
范围 | 描述 | 类型 |
---|---|---|
config | 用于定义或覆盖中间件配置 | Object |
resolve | 中间件文件夹的路径(对于外部中间件有用) | String |
内部中间件配置参考
¥Internal middlewares configuration reference
Strapi 的核心包括以下内部中间件,主要用于性能、安全性和错误处理:
¥Strapi's core includes the following internal middlewares, mostly used for performances, security and error handling:
中间件 | 默认添加 | 必需的 |
---|---|---|
body | 是的 | 是的 |
compression | 不 | 不 |
cors | 是的 | 是的 |
errors | 是的 | 是的 |
favicon | 是的 | 是的 |
ip | 不 | 不 |
logger | 是的 | 不 |
poweredBy | 是的 | 不 |
query | 是的 | 是的 |
response-time | 不 | 不 |
responses | 是的 | 是的 |
public | 是的 | 是的 |
security | 是的 | 是的 |
session | 是的 | 不 |
body
body
中间件基于 koa-body。它接受以下选项:
¥The body
middleware is based on koa-body. It accepts the following options:
选项 | 描述 | 类型 | 默认 |
---|---|---|---|
multipart | 解析多部分主体 | Boolean | true |
patchKoa | Koa 的 ctx.request 的补丁请求主体 | Boolean | true |
jsonLimit | JSON 主体的字节(如果是整数)限制 | String 或 Integer | 1mb |
formLimit | 表单主体的字节(如果是整数)限制 | String 或 Integer | 56kb |
textLimit | 文本正文的字节(如果是整数)限制 | String 或 Integer | 56kb |
encoding | 设置传入表单字段的编码 | String | utf-8 |
formidable | 传递给 formidable 多部分解析器的选项(参见 节点强大的文档)。 | Object | undefined |
有关 koa-body
可用选项的完整列表,请检查 koa-body 文档。
¥For a full list of available options for koa-body
, check the koa-body documentation.
Example: Custom configuration for the body middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::body',
config: {
jsonLimit: '3mb',
formLimit: '10mb',
textLimit: '256kb',
encoding: 'gbk',
},
},
// ...
]
export default [
// ...
{
name: 'strapi::body',
config: {
jsonLimit: '3mb',
formLimit: '10mb',
textLimit: '256kb',
encoding: 'gbk',
},
},
// ...
]
compression
compression
中间件基于 koa-compress。它接受以下选项:
¥The compression
middleware is based on koa-compress. It accepts the following options:
选项 | 描述 | 类型 | 默认 |
---|---|---|---|
threshold | 要压缩的最小响应大小(以字节为单位) | String 或 Integer | 1kb |
br | 切换 Brotli 压缩 | Boolean | true |
gzip | 切换 gzip 压缩 | Boolean | false |
deflate | 切换放气压缩 | Boolean | false |
defaultEncoding | 指定对没有 Accept-Encoding 标头的请求使用什么编码器 | String | identity |
Example: Custom configuration for the compression middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::compression',
config: {
br: false
},
},
// ...
]
export default [
// ...
{
name: 'strapi::compression',
config: {
br: false
},
},
// ...
]
cors
这个安全中间件是关于跨域资源共享(CORS)的,基于 @koa/cors。它接受以下选项:
¥This security middleware is about cross-origin resource sharing (CORS) and is based on @koa/cors. It accepts the following options:
选项 | 类型 | 描述 | 默认值 |
---|---|---|---|
origin | 配置 Access-Control-Allow-Origin 标头 | String 或 Array | '*' |
maxAge | 配置 Access-Control-Max-Age 标头,以秒为单位 | String 或 Number | 31536000 |
credentials | 配置 Access-Control-Allow-Credentials 标头 | Boolean | true |
methods | 配置 Access-Control-Allow-Methods 标头 | Array 或 String | ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'] |
headers | 配置 Access-Control-Allow-Headers 标头 | Array 或 String | Access-Control-Request-Headers 中传递的请求标头 |
keepHeaderOnError | 如果抛出错误,请将设置标头添加到 err.header | Boolean | false |
Example: Custom configuration for the cors middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::cors',
config: {
origin: ['https://example.com', 'https://subdomain.example.com', 'https://someotherwebsite.org'],
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],
keepHeaderOnError: true,
},
},
// ...
]
export default [
// ...
{
name: 'strapi::cors',
config: {
origin: ['example.com', 'subdomain.example.com', 'someotherwebsite.org'],
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],
keepHeaderOnError: true,
},
},
// ...
]
errors
错误中间件处理代码抛出的 errors。它根据错误类型为响应设置适当的 HTTP 状态。默认情况下,任何不应向终端用户公开的错误都将导致 500 HTTP 响应。
¥The errors middleware handles errors thrown by the code. Based on the type of error it sets the appropriate HTTP status to the response. By default, any error not supposed to be exposed to the end user will result in a 500 HTTP response.
中间件没有任何配置选项。
¥The middleware doesn't have any configuration options.
favicon
favicon
中间件服务于 favicon,基于 koa-favicon。它接受以下选项:
¥The favicon
middleware serves the favicon and is based on koa-favicon. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
path | 网站图标文件的路径 | String | 'favicon.ico' |
maxAge | 缓存控制 max-age 指令,以毫秒为单位 | Integer | 86400000 |
Example: Custom configuration for the favicon middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::favicon',
config: {
path: './public/uploads/custom-fav-abc123.ico'
},
},
// ...
]
export default [
// ...
{
name: 'strapi::favicon',
config: {
path: './public/uploads/custom-fav-abc123.ico'
},
},
// ...
]
ip
ip
中间件是基于 koa-ip 的 IP 过滤中间件。它接受以下选项:
¥The ip
middleware is an IP filter middleware based on koa-ip. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
whitelist | 列入白名单的 IP | Array | [] |
blacklist | 列入黑名单的 IP | Array | [] |
whitelist
和 blacklist
选项支持通配符(例如 whitelist: ['192.168.0.*', '127.0.0.*']
)和点差(例如 whitelist: ['192.168.*.[3-10]']
)。
¥The whitelist
and blacklist
options support wildcards (e.g. whitelist: ['192.168.0.*', '127.0.0.*']
) and spreads (e.g. whitelist: ['192.168.*.[3-10]']
).
Example: Custom configuration for the ip middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::ip',
config: {
whitelist: ['192.168.0.*', '192.168.1.*', '123.123.123.123'],
blacklist: ['1.116.*.*', '103.54.*.*'],
},
},
// ...
]
export default [
// ...
{
name: 'strapi::ip',
config: {
whitelist: ['192.168.0.*', '192.168.1.*', '123.123.123.123'],
blacklist: ['1.116.*.*', '103.54.*.*'],
},
},
// ...
]
logger
logger
中间件用于记录请求。
¥The logger
middleware is used to log requests.
要为 logger
中间件定义自定义配置,请创建专用配置文件 (./config/logger.js
)。它应该导出一个对象,该对象必须是完整或部分 winstonjs 日志器配置。该对象将在服务器启动时与 Strapi 的默认日志器配置合并。
¥To define a custom configuration for the logger
middleware, create a dedicated configuration file (./config/logger.js
). It should export an object that must be a complete or partial winstonjs logger configuration. The object will be merged with Strapi's default logger configuration on server start.
Example: Custom configuration for the logger middleware
- JavaScript
- TypeScript
'use strict';
const {
winston,
formats: { prettyPrint, levelFilter },
} = require('@strapi/logger');
module.exports = {
transports: [
new winston.transports.Console({
level: 'http',
format: winston.format.combine(
levelFilter('http'),
prettyPrint({ timestamps: 'YYYY-MM-DD hh:mm:ss.SSS' })
),
}),
],
};
'use strict';
const {
winston,
formats: { prettyPrint, levelFilter },
} = require('@strapi/logger');
export default {
transports: [
new winston.transports.Console({
level: 'http',
format: winston.format.combine(
levelFilter('http'),
prettyPrint({ timestamps: 'YYYY-MM-DD hh:mm:ss.SSS' })
),
}),
],
};
poweredBy
poweredBy
中间件在响应头中添加了 X-Powered-By
参数。它接受以下选项:
¥The poweredBy
middleware adds a X-Powered-By
parameter to the response header. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
poweredBy | X-Powered-By 标头的值 | String | 'Strapi <strapi.io>' |
details Example: Custom configuration for the poweredBy middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::poweredBy',
config: {
poweredBy: 'Some Awesome Company <example.com>'
},
},
// ...
]
export default [
// ...
{
name: 'strapi::poweredBy',
config: {
poweredBy: 'Some Awesome Company <example.com>'
},
},
// ...
]
query
query
中间件是基于 qs 的查询解析器。它接受以下选项:
¥The query
middleware is a query parser based on qs. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
strictNullHandling | 区分空值和空字符串(参见 质量标准文档) | Boolean | true |
arrayLimit | 解析数组时的最大索引限制(参见 质量标准文档) | Number | 100 |
depth | 解析对象时嵌套对象的最大深度(参见 质量标准文档) | Number | 20 |
Example: Custom configuration for the query middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::query',
config: {
arrayLimit: 50,
depth: 10,
},
},
// ...
]
export default [
// ...
{
name: 'strapi::query',
config: {
arrayLimit: 50,
depth: 10,
},
},
// ...
]
response-time
response-time
中间件启用响应标头的 X-Response-Time
(以毫秒为单位)。
¥The response-time
middleware enables the X-Response-Time
(in milliseconds) for the response header.
中间件没有任何配置选项。
¥The middleware doesn't have any configuration options.
public
public
中间件是一个静态文件服务中间件,基于 koa-static。它接受以下选项:
¥The public
middleware is a static file serving middleware, based on koa-static. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
maxAge | 缓存控制 max-age 指令,以毫秒为单位 | Integer | 60000 |
你可以通过编辑 服务器配置文件.conf 文件来自定义公用文件夹的路径。
¥You can customize the path of the public folder by editing the server configuration file.
Example: Custom configuration for the public middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::public',
config: {
defer: true,
index: env('INDEX_PATH', 'index-dev.html')
},
},
// ...
]
export default [
// ...
{
name: 'strapi::public',
config: {
defer: true,
index: env('INDEX_PATH', 'index-dev.html')
},
},
// ...
]
security
安全中间件基于 koa-helmet。它接受以下选项:
¥The security middleware is based on koa-helmet. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
crossOriginEmbedderPolicy | 将 Cross-Origin-Embedder-Policy 标头设置为 require-corp | Boolean | false |
crossOriginOpenerPolicy | 设置 Cross-Origin-Opener-Policy 标头 | Boolean | false |
crossOriginResourcePolicy | 设置 Cross-Origin-Resource-Policy 标头 | Boolean | false |
originAgentCluster | 设置 Origin-Agent-Cluster 标头 | Boolean | false |
contentSecurityPolicy | 设置 Content-Security-Policy 标头 | Object | - |
xssFilter | 通过将 X-XSS-Protection 标头设置为 0 来禁用浏览器的跨站点脚本过滤器 | Boolean | false |
hsts | 设置 HTTP 严格传输安全 (HSTS) 策略的选项。 | Object | * |
hsts.maxAge | HSTS 生效的秒数 | Integer | 31536000 |
hsts.includeSubDomains | 将 HSTS 应用于主机的所有子域 | Boolean | true |
frameguard | 设置 X-Frame-Options 标头以帮助减轻点击劫持攻击,设置为 false 以禁用 | Boolean 或 Object | * |
frameguard.action | 值必须是 deny 或 sameorigin | String | sameorigin |
当使用任何第三方上传提供者时,通常需要在此处设置自定义配置。请参阅需要配置选项的提供者文档。
¥When using any 3rd party upload provider, generally it's required to set a custom configuration here. Please see the provider documentation for which configuration options are required.
默认指令包括 market-assets.strapi.io
值。该值是为 应用内市场 设置的,可以安全保存。
¥The default directives include a market-assets.strapi.io
value. This value is set for the in-app market and is safe to keep.
Example: Custom configuration for the security middleware for using the AWS-S3 provider
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': [
"'self'",
'data:',
'blob:',
'market-assets.strapi.io',
'yourBucketName.s3.yourRegion.amazonaws.com',
],
'media-src': [
"'self'",
'data:',
'blob:',
'market-assets.strapi.io',
'yourBucketName.s3.yourRegion.amazonaws.com',
],
upgradeInsecureRequests: null,
},
},
},
},
// ...
]
export default [
// ...
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': [
"'self'",
'data:',
'blob:',
'market-assets.strapi.io',
'yourBucketName.s3.yourRegion.amazonaws.com',
],
'media-src': [
"'self'",
'data:',
'blob:',
'market-assets.strapi.io',
'yourBucketName.s3.yourRegion.amazonaws.com',
],
upgradeInsecureRequests: null,
},
},
},
},
// ...
]
session
session
中间件允许使用基于 cookie 的会话,基于 koa-session。它接受以下选项:
¥The session
middleware allows the use of cookie-based sessions, based on koa-session. It accepts the following options:
选项 | 描述 | 类型 | 默认值 |
---|---|---|---|
key | Cookie 键 | String | 'koa.sess' |
maxAge | Cookie 的最长生命周期(以毫秒为单位)。使用 'session' 将使 cookie 在会话关闭时过期。 | Integer 或 'session' | 86400000 |
autoCommit | 自动提交标头 | Boolean | true |
overwrite | 可以覆盖也可以不覆盖 | Boolean | true |
httpOnly | 是否为 httpOnly。使用 httpOnly 有助于减轻跨站点脚本 (XSS) 攻击。 | Boolean | true |
signed | 签署 cookies | Boolean | true |
rolling | 强制在每个响应上设置会话标识符 cookie。 | Boolean | false |
renew | 当会话即将过期时更新会话,以便用户保持登录状态。 | Boolean | false |
secure | 强制使用 HTTPS | Boolean | true 正在生产,false 否则 |
sameSite | 将 cookie 限制为第一方或同一站点上下文 | String | null |
Example: Custom configuration for the session middleware
- JavaScript
- TypeScript
module.exports = [
// ...
{
name: 'strapi::session',
config: {
rolling: true,
renew: true
},
},
// ...
]
export default [
// ...
{
name: 'strapi::session',
config: {
rolling: true,
renew: true
},
},
// ...
]