Skip to main content

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 是一个异步函数,它期望返回一个包含具有 sourceheaders 属性的对象的数组:

¥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 是响应标头对象的数组,具有 keyvalue 属性。

    ¥headers is an array of response header objects, with key and value properties.

  • basePathfalseundefined - 如果为 false,则匹配时不会包含 basePath,只能用于外部重写。

    ¥basePath: false or undefined - if false the basePath won't be included when matching, can be used for external rewrites only.

  • localefalseundefined - 匹配时是否不应包含区域设置。

    ¥locale: false or undefined - whether the locale should not be included when matching.

  • has 是具有 typekeyvalue 属性的 有对象 的数组。

    ¥has is an array of has objects with the type, key and value properties.

  • missing 是具有 typekeyvalue 属性的 丢失对象 的数组。

    ¥missing is an array of missing objects with the type, key and value properties.

在包含页面和 /public 文件的文件系统之前检查标头。

¥Headers are checked before the filesystem which includes pages and /public files.

标头覆盖行为

¥Header Overriding Behavior

如果两个标头匹配相同的路径并设置相同的标头键,则最后一个标头键将覆盖第一个标头键。使用以下标头,路径 /hello 将导致标头 x-helloworld,因为最后设置的标头值为 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',
},
],
},
]
},
}

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

hasmissing 项目可以具有以下字段:

¥has and missing items can have the following fields:

  • typeString - 必须是 headercookiehostquery

    ¥type: String - must be either header, cookie, host, or query.

  • keyString - 所选类型中要匹配的键。

    ¥key: String - the key from the selected type to match against.

  • valueStringundefined - 要检查的值,如果未定义,则任何值都会匹配。类似正则表达式的字符串可用于捕获值的特定部分,例如 如果值 first-(?<paramName>.*) 用于 first-second,则 second 将可在目标中与 :paramName 一起使用。

    ¥value: String or undefined - 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 value first-(?<paramName>.*) is used for first-second then second 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, immutableCache-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添加了标题。