Skip to main content

中间件配置

🌐 Middlewares configuration

Page summary:

/config/middlewares 下达全局中间件,启用自定义名称或解析,并公开内置配置选项。

Different types of middlewares

在 Strapi 中,3 个中间件概念共存:

🌐 In Strapi, 3 middleware concepts coexist:

  • 全局中间件 是为整个 Strapi 服务器应用配置和启用的。这些中间件可以应用于应用级别或 API 级别。
    本指南描述了如何实现它们。
    插件也可以添加全局中间件(参见服务器 API 文档)。
  • 路由中间件 的作用范围更有限,并且作为路由级别的中间件进行配置和使用。它们在 路由文档 中有描述。
  • 文档服务中间件 适用于文档服务 API,并且有其自己的 实现 和相关的 生命周期钩子

./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:

./config/middlewares.js

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',
];
Tip

如果你不确定将中间件放置在堆栈中的位置,请将其添加到列表的末尾。

🌐 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
插件middlewares 插件接口的属性 中的 strapi-server.js 导出plugin::plugin-name.middleware-name
外部可以是:
  • 通过 npm
  • 安装的节点模块,或者本地中间件(即本地创建并在 ./config/middlewares.js 中配置的自定义中间件)。
-

由于它们是直接从配置文件中配置和解析的,因此没有命名约定。

可选配置

🌐 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。它使用 `node-formidable` 库来处理文件。body 接受以下选项:

选项描述类型默认值
multipart解析多部分请求体Booleantrue
patchKoa将请求体修补到 Koa 的 ctx.requestBooleantrue
jsonLimitJSON 请求体的字节(如果为整数)限制StringInteger1mb
formLimit表单请求体的字节(如果为整数)限制StringInteger56kb
textLimit文本请求体的字节(如果为整数)限制StringInteger56kb
encoding设置传入表单字段的编码Stringutf-8
formidable传递给 formidable 多部分解析器的选项(参见 node-formidable documentation)。Objectundefined

有关 koa-body 的所有可用选项的完整列表,请查看 koa-body documentation

示例:用于主体中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::body',
config: {
jsonLimit: '3mb',
formLimit: '10mb',
textLimit: '256kb',
encoding: 'gbk',
},
},
// ...
]

compression

compression 中间件基于 koa-compress。它接受以下选项:

选项描述类型默认值
threshold压缩的最小响应大小(字节)StringInteger1kb
br切换 Brotli 压缩Booleantrue
gzip切换 gzip 压缩Booleanfalse
deflate切换 deflate 压缩Booleanfalse
defaultEncoding指定在请求中没有 Accept-Encoding 头时使用哪些编码器Stringidentity
示例:压缩中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
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-OriginStringArrayFunction'*'
maxAge配置 Access-Control-Max-Age 头,以秒为单位StringNumber31536000
credentials配置 Access-Control-Allow-CredentialsBooleantrue
methods配置 Access-Control-Allow-MethodsArrayString['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']
headers配置 Access-Control-Allow-HeadersArrayString请求头通过 Access-Control-Request-Headers 传递
keepHeaderOnError如果抛出错误,向 err.header 添加设置的头Booleanfalse
示例:cors 中间件的自定义配置
./config/middlewares.js

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,
},
},
// ...
]
示例:作为参数在函数中为cors中间件自定义配置

origin 可以接收一个符合此签名的函数作为参数

./config/middlewares.ts

export default [
// ...
{
name: 'strapi::cors',
config: {
origin: (ctx): string | string[] => {
const origin = ctx.request.header.origin;
if (origin === 'http://localhost:3000') {
return origin; // The returns will be part of the Access-Control-Allow-Origin header
}

return ''; // Fail cors check
}
},
},
// ...
]

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 中间件用于提供网站图标,并基于 koa-favicon。它接受以下选项:

选项描述类型默认值
pathfavicon 文件的路径String'favicon.ico'
maxAge缓存控制最大存活时间指令,以毫秒为单位Integer86400000
示例:favicon 中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::favicon',
config: {
path: './public/uploads/custom-fav-abc123.ico'
},
},
// ...
]

ip

ip 中间件是基于 koa-ip 的 IP 过滤中间件。它接受以下选项:

选项描述类型默认值
whitelist白名单 IPArray[]
blacklist黑名单 IPArray[]
Tip

whitelistblacklist 选项支持通配符(例如 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]']).

示例:ip 中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
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 的默认日志配置合并。

示例:日志器中间件的自定义配置
./config/logger.js

'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' })
),
}),
],
};

poweredBy

poweredBy 中间件向响应头添加了一个 X-Powered-By 参数。它接受以下选项:

🌐 The poweredBy middleware adds a X-Powered-By parameter to the response header. It accepts the following options:

选项描述类型默认值
poweredByX-Powered-By 头的值String'Strapi <strapi.io>'
详情 示例:poweredBy 中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::poweredBy',
config: {
poweredBy: 'Some Awesome Company <example.com>'
},
},
// ...
]

query

query 中间件是基于 qs 的查询解析器。它接受以下选项:

选项描述类型默认值
strictNullHandling区分空值和空字符串(参见 qs documentationBooleantrue
arrayLimit解析数组时的最大索引限制(参见 qs documentationNumber100
depth解析对象时嵌套对象的最大深度(参见 qs documentationNumber20
Note

查询字符串中的括号样式数组(populatefieldsfilters 和嵌套键)使用 arrayLimit 通过 qs 进行解析。当列表超出该限制时,qs 可能会返回对象形状的值而不是数组。Strapi 可能会因此拒绝查询或返回与此设置无关的错误。当需要更长列表时,请增加 arrayLimit。更大的值允许更长的查询字符串,并增加每个请求的解析工作量。

🌐 Bracket-style arrays in the query string (populate, fields, filters, and nested keys) are parsed with qs using arrayLimit. When a list grows past that limit, qs can yield object-shaped values instead of arrays. Strapi may then reject the query or return errors that do not point to this setting. Increase arrayLimit when you need longer lists. Larger values allow longer query strings and increase parsing work on each request.

示例:查询中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::query',
config: {
arrayLimit: 50,
depth: 10,
},
},
// ...
]
示例:针对长 REST 查询列表提高 arrayLimit

使用适合你最长括号编码列表的值(例如许多 populate[n] 条目)。根据你的需求和可接受的解析成本调整这个数字。

🌐 Use a value that fits your longest bracket-encoded lists (for example many populate[n] entries). Adjust the number based on your needs and acceptable parsing cost.

./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::query',
config: {
arrayLimit: 200,
},
},
// ...
]

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。它接受以下选项:

选项描述类型默认值
maxAge缓存控制最大年龄指令,单位为毫秒Integer60000
Note

config 中使用 camelCase 的 maxAge 键,与表格匹配。Strapi 5 仅从你的 strapi::public 中间件 config 读取此字段,并将其传递给 koa-static(参见 packages/core/core/src/middlewares/public.ts);defer 固定在核心中间件中,因此你在这里无需设置它。

🌐 Use the camelCase maxAge key in config, matching the table. Strapi 5 reads only this field from your strapi::public middleware config and passes it to koa-static (see packages/core/core/src/middlewares/public.ts); defer is fixed inside the core middleware, so you do not set it here.

Tip

你可以通过编辑 服务器配置文件 来自定义公共文件夹的路径。

🌐 You can customize the path of the public folder by editing the server configuration file.

示例:公共中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::public',
config: {
maxAge: 86400000, // 1 day in milliseconds
},
},
// ...
]

security

安全中间件基于 koa-helmet。它接受以下选项:

选项描述类型默认值
crossOriginEmbedderPolicyCross-Origin-Embedder-Policy 头设置为 require-corpBooleanfalse
crossOriginOpenerPolicy设置 Cross-Origin-Opener-PolicyBooleanfalse
crossOriginResourcePolicy设置 Cross-Origin-Resource-Policy 头部Booleanfalse
originAgentCluster设置 Origin-Agent-Cluster 头部Booleanfalse
contentSecurityPolicy设置 Content-Security-Policy 头部Object-
xssFilter通过将 X-XSS-Protection 头设置为 0 来禁用浏览器的跨站脚本过滤器Booleanfalse
hsts设置 HTTP 严格传输安全 (HSTS) 策略的选项。Object-
hsts.maxAgeHSTS 生效的秒数Integer31536000
hsts.includeSubDomains对主机的所有子域应用 HSTSBooleantrue
frameguard设置 X-Frame-Options 头以帮助减轻点击劫持攻击,设置为 false 以禁用BooleanObject-
frameguard.action值必须是 denysameoriginStringsameorigin
Tip

在使用任何第三方上传提供商时,通常需要在此处设置自定义配置。请参阅提供商文档以了解哪些配置选项是必需的。

🌐 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.

Note

默认指令包括一个 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.

示例:用于使用 AWS-S3 提供程序的安全中间件的自定义配置
./config/middlewares.js

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,
},
},
},
},
// ...
]

session

session 中间件允许使用基于 cookie 的会话,基于 koa-session。它接受以下选项:

选项描述类型默认值
keyCookie 键String'koa.sess'
maxAgeCookie 的最大有效期,单位为毫秒。使用 'session' 将在会话关闭时使 cookie 过期。Integer'session'86400000
autoCommit自动提交标题Booleantrue
overwrite是否可以覆盖Booleantrue
httpOnly是否是 httpOnly。使用 httpOnly 有助于缓解跨站脚本(XSS)攻击。Booleantrue
signed签署 cookiesBooleantrue
rolling强制在每个响应中设置会话标识符 cookie。Booleanfalse
renew当会话即将过期时续订会话,以便用户保持登录状态。Booleanfalse
secure强制使用 HTTPSBoolean在生产环境中为 true,否则为 false
sameSite将 Cookie 限制为第一方或同站点上下文Stringnull
示例:会话中间件的自定义配置
./config/middlewares.js

module.exports = [
// ...
{
name: 'strapi::session',
config: {
rolling: true,
renew: true
},
},
// ...
]