headers
headers 允许你在给定路径上传入请求的响应上设置自定义 HTTP 标头。
¥Headers allow you to set custom HTTP headers on the response to an incoming request on a given path.
要设置自定义 HTTP 标头,你可以在 next.config.js
中使用 headers
键:
¥To set custom HTTP headers you can use the headers
key in next.config.js
:
module.exports = {
async headers() {
return [
{
source: '/about',
headers: [
{
key: 'x-custom-header',
value: 'my custom header value',
},
{
key: 'x-another-custom-header',
value: 'my other custom header value',
},
],
},
]
},
}
headers
是一个异步函数,它期望返回一个包含具有 source
和 headers
属性的对象的数组:
¥headers
is an async function that expects an array to be returned holding objects with source
and headers
properties:
-
source
是传入请求路径模式。¥
source
is the incoming request path pattern. -
headers
是响应标头对象的数组,具有key
和value
属性。¥
headers
is an array of response header objects, withkey
andvalue
properties. -
basePath
:false
或undefined
- 如果为 false,则匹配时不会包含 basePath,只能用于外部重写。¥
basePath
:false
orundefined
- if false the basePath won't be included when matching, can be used for external rewrites only. -
locale
:false
或undefined
- 匹配时是否不应包含区域设置。¥
locale
:false
orundefined
- whether the locale should not be included when matching. -
has
是具有type
、key
和value
属性的 有对象 的数组。¥
has
is an array of has objects with thetype
,key
andvalue
properties. -
missing
是具有type
、key
和value
属性的 丢失对象 的数组。¥
missing
is an array of missing objects with thetype
,key
andvalue
properties.
在包含页面和 /public
文件的文件系统之前检查标头。
¥Headers are checked before the filesystem which includes pages and /public
files.
标头覆盖行为
¥Header Overriding Behavior
如果两个标头匹配相同的路径并设置相同的标头键,则最后一个标头键将覆盖第一个标头键。使用以下标头,路径 /hello
将导致标头 x-hello
为 world
,因为最后设置的标头值为 world
。
¥If two headers match the same path and set the same header key, the last header key will override the first. Using the below headers, the path /hello
will result in the header x-hello
being world
due to the last header value set being world
.
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'x-hello',
value: 'there',
},
],
},
{
source: '/hello',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
]
},
}
路径匹配
¥Path Matching
允许路径匹配,例如 /blog/:slug
将匹配 /blog/hello-world
(无嵌套路径):
¥Path matches are allowed, for example /blog/:slug
will match /blog/hello-world
(no nested paths):
module.exports = {
async headers() {
return [
{
source: '/blog/:slug',
headers: [
{
key: 'x-slug',
value: ':slug', // Matched parameters can be used in the value
},
{
key: 'x-slug-:slug', // Matched parameters can be used in the key
value: 'my other custom header value',
},
],
},
]
},
}
通配符路径匹配
¥Wildcard Path Matching
要匹配通配符路径,你可以在参数后使用 *
,例如 /blog/:slug*
将匹配 /blog/a/b/c/d/hello-world
:
¥To match a wildcard path you can use *
after a parameter, for example /blog/:slug*
will match /blog/a/b/c/d/hello-world
:
module.exports = {
async headers() {
return [
{
source: '/blog/:slug*',
headers: [
{
key: 'x-slug',
value: ':slug*', // Matched parameters can be used in the value
},
{
key: 'x-slug-:slug*', // Matched parameters can be used in the key
value: 'my other custom header value',
},
],
},
]
},
}
正则表达式路径匹配
¥Regex Path Matching
要匹配正则表达式路径,你可以将正则表达式括在参数后面的括号中,例如 /blog/:slug(\\d{1,})
将匹配 /blog/123
但不匹配 /blog/abc
:
¥To match a regex path you can wrap the regex in parenthesis after a parameter, for example /blog/:slug(\\d{1,})
will match /blog/123
but not /blog/abc
:
module.exports = {
async headers() {
return [
{
source: '/blog/:post(\\d{1,})',
headers: [
{
key: 'x-post',
value: ':post',
},
],
},
]
},
}
以下字符 (
、)
、{
、}
、:
、*
、+
、?
用于正则表达式路径匹配,因此当在 source
中用作非特殊值时,必须通过在其前面添加 \\
来转义它们:
¥The following characters (
, )
, {
, }
, :
, *
, +
, ?
are used for regex path matching, so when used in the source
as non-special values they must be escaped by adding \\
before them:
module.exports = {
async headers() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
headers: [
{
key: 'x-header',
value: 'value',
},
],
},
]
},
}
标头、Cookie 和查询匹配
¥Header, Cookie, and Query Matching
仅当标头、cookie 或查询值也与 has
字段匹配或与 missing
字段不匹配时才应用标头。source
和所有 has
项目都必须匹配,并且所有 missing
项目不得匹配才能应用标头。
¥To only apply a header when header, cookie, or query values also match the has
field or don't match the missing
field can be used. Both the source
and all has
items must match and all missing
items must not match for the header to be applied.
has
和 missing
项目可以具有以下字段:
¥has
and missing
items can have the following fields:
-
type
:String
- 必须是header
、cookie
、host
或query
。¥
type
:String
- must be eitherheader
,cookie
,host
, orquery
. -
key
:String
- 所选类型中要匹配的键。¥
key
:String
- the key from the selected type to match against. -
value
:String
或undefined
- 要检查的值,如果未定义,则任何值都会匹配。类似正则表达式的字符串可用于捕获值的特定部分,例如 如果值first-(?<paramName>.*)
用于first-second
,则second
将可在目标中与:paramName
一起使用。¥
value
:String
orundefined
- the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the valuefirst-(?<paramName>.*)
is used forfirst-second
thensecond
will be usable in the destination with:paramName
.
module.exports = {
async headers() {
return [
// if the header `x-add-header` is present,
// the `x-another-header` header will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-add-header',
},
],
headers: [
{
key: 'x-another-header',
value: 'hello',
},
],
},
// if the header `x-no-header` is not present,
// the `x-another-header` header will be applied
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-no-header',
},
],
headers: [
{
key: 'x-another-header',
value: 'hello',
},
],
},
// if the source, query, and cookie are matched,
// the `x-authorized` header will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// header key/values since value is provided and
// doesn't use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
headers: [
{
key: 'x-authorized',
value: ':authorized',
},
],
},
// if the header `x-authorized` is present and
// contains a matching value, the `x-another-header` will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
headers: [
{
key: 'x-another-header',
value: ':authorized',
},
],
},
// if the host is `example.com`,
// this header will be applied
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
headers: [
{
key: 'x-another-header',
value: ':authorized',
},
],
},
]
},
}
具有 basePath 支持的标头
¥Headers with basePath support
当利用带有标头的 basePath
支持 时,每个 source
都会自动添加 basePath
前缀,除非你将 basePath: false
添加到标头:
¥When leveraging basePath
support with headers each source
is automatically prefixed with the basePath
unless you add basePath: false
to the header:
module.exports = {
basePath: '/docs',
async headers() {
return [
{
source: '/with-basePath', // becomes /docs/with-basePath
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
source: '/without-basePath', // is not modified since basePath: false is set
headers: [
{
key: 'x-hello',
value: 'world',
},
],
basePath: false,
},
]
},
}
支持 i18n 的标头
¥Headers with i18n support
当利用带有标头的 i18n
支持 时,每个 source
都会自动添加前缀以处理配置的 locales
,除非你将 locale: false
添加到标头。如果使用 locale: false
,则必须在 source
前面加上区域设置前缀,才能正确匹配。
¥When leveraging i18n
support with headers each source
is automatically prefixed to handle the configured locales
unless you add locale: false
to the header. If locale: false
is used you must prefix the source
with a locale for it to be matched correctly.
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async headers() {
return [
{
source: '/with-locale', // automatically handles all locales
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
locale: false,
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
locale: false,
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
]
},
}
缓存控制
¥Cache-Control
Next.js 设置 public, max-age=31536000, immutable
的 Cache-Control
标头以实现真正不可变的资源。它不能被覆盖。这些不可变文件的文件名中包含 SHA 哈希值,因此可以无限期安全地缓存它们。例如,静态图片导入。你无法在 next.config.js
中为这些资源设置 Cache-Control
标头。
¥Next.js sets the Cache-Control
header of public, max-age=31536000, immutable
for truly immutable assets. It cannot be overridden. These immutable files contain a SHA-hash in the file name, so they can be safely cached indefinitely. For example, Static Image Imports. You cannot set Cache-Control
headers in next.config.js
for these assets.
但是,你可以为其他响应或数据设置 Cache-Control
标头。
¥However, you can set Cache-Control
headers for other responses or data.
通过 App Router 了解有关 caching 的更多信息。
¥Learn more about caching with the App Router.
选项
¥Options
CORS
跨域资源共享 (CORS) 是一项安全功能,允许你控制哪些站点可以访问你的资源。你可以设置 Access-Control-Allow-Origin
标头以允许特定源访问你的路由处理程序。
¥Cross-Origin Resource Sharing (CORS) is a security feature that allows you to control which sites can access your resources. You can set the Access-Control-Allow-Origin
header to allow a specific origin to access your Route Handlers.
async headers() {
return [
{
source: "/api/:path*",
headers: [
{
key: "Access-Control-Allow-Origin",
value: "*", // Set your origin
},
{
key: "Access-Control-Allow-Methods",
value: "GET, POST, PUT, DELETE, OPTIONS",
},
{
key: "Access-Control-Allow-Headers",
value: "Content-Type, Authorization",
},
],
},
];
},
X-DNS 预取控制
¥X-DNS-Prefetch-Control
这个标题 控制 DNS 预取,允许浏览器主动对外部链接、图片、CSS、JavaScript 等进行域名解析。此预取是在后台执行的,因此 DNS 更有可能在需要引用的项目时得到解析。这可以减少用户单击链接时的延迟。
¥This header controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the DNS is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
}
严格的运输安全
¥Strict-Transport-Security
这个标题 通知浏览器只能使用 HTTPS 访问,而不是使用 HTTP。使用下面的配置,所有当前和未来的子域都将在 max-age
的 2 年时间内使用 HTTPS。这会阻止访问只能通过 HTTP 提供服务的页面或子域。
¥This header informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for a max-age
of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.
如果你要部署到 Vercel,则不需要此标头,因为它会自动添加到所有部署中,除非你在 next.config.js
中声明 headers
。
¥If you're deploying to Vercel, this header is not necessary as it's automatically added to all deployments unless you declare headers
in your next.config.js
.
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}
X 框架选项
¥X-Frame-Options
这个标题 指示是否允许该站点在 iframe
内显示。这可以防止点击劫持攻击。
¥This header indicates whether the site should be allowed to be displayed within an iframe
. This can prevent against clickjacking attacks.
该标头已被 CSP 的 frame-ancestors
选项取代,该选项在现代浏览器中具有更好的支持(有关配置详细信息,请参阅 内容安全政策)。
¥This header has been superseded by CSP's frame-ancestors
option, which has better support in modern browsers (see Content Security Policy for configuration details).
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
}
权限策略
¥Permissions-Policy
这个标题 允许你控制浏览器中可以使用哪些功能和 API。它以前被命名为 Feature-Policy
。
¥This header allows you to control which features and APIs can be used in the browser. It was previously named Feature-Policy
.
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}
X-内容类型选项
¥X-Content-Type-Options
如果未显式设置 Content-Type
标头,这个标题 会阻止浏览器尝试猜测内容类型。这可以防止允许用户上传和共享文件的网站遭到 XSS 攻击。
¥This header prevents the browser from attempting to guess the type of content if the Content-Type
header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files.
例如,用户尝试下载图片,但将其视为不同的 Content-Type
(如可执行文件),这可能是恶意的。此标头也适用于下载浏览器扩展。该标头的唯一有效值是 nosniff
。
¥For example, a user trying to download an image, but having it treated as a different Content-Type
like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header is nosniff
.
{
key: 'X-Content-Type-Options',
value: 'nosniff'
}
来路政策
¥Referrer-Policy
这个标题 控制从当前网站(源)导航到另一个网站时浏览器包含的信息量。
¥This header controls how much information the browser includes when navigating from the current website (origin) to another.
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
内容安全策略
¥Content-Security-Policy
了解有关将 内容安全政策 添加到你的应用的更多信息。
¥Learn more about adding a Content Security Policy to your application.
版本历史
¥Version History
版本 | 变化 |
---|---|
v13.3.0 | 添加了 missing 。 |
v10.2.0 | 添加了 has 。 |
v9.5.0 | 添加了标题。 |