Заголовки
Заголовки позволяют задавать пользовательские HTTP-заголовки в ответе на входящий запрос на заданном пути.
Чтобы установить пользовательские HTTP-заголовки, можно использовать ключ headers в 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.
source— шаблон пути входящего запроса.headers— массив объектов заголовков ответа со свойствамиkeyиvalue.basePath:falseилиundefined— если false, basePath не будет включен при сопоставлении, может использоваться только для внешних перенаправлений.locale:falseилиundefined— следует ли не включать локаль при сопоставлении.has— массив объектов с свойствамиtype,keyиvalue.missing— массив отсутствующих объектов со свойствамиtype,keyиvalue.
Заголовки проверяются до проверки файловой системы, которая включает страницы и файлы /public.
Поведение переопределения заголовков
Если два заголовка соответствуют одному и тому же пути и задают один и тот же ключ заголовка, последний ключ заголовка переопределит первый. Используя заголовки ниже, путь /hello приведет к тому, что заголовок x-hello будет world из-за того, что последнее заданное значение заголовка — world.
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'x-hello',
value: 'there',
},
],
},
{
source: '/hello',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
]
},
}Сопоставление путей
Разрешены соответствия путей, например, /blog/:slug будет соответствовать /blog/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',
},
],
},
]
},
}Сопоставление путей с подстановкой
Чтобы сопоставить путь с подстановкой, можно использовать * после параметра, например, /blog/:slug* будет соответствовать /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',
},
],
},
]
},
}Сопоставление путей с использованием регулярных выражений
Чтобы сопоставить путь с использованием регулярного выражения, можно заключить регулярное выражение в скобки после параметра, например, /blog/:slug(\\d{1,}) будет соответствовать /blog/123, но не /blog/abc:
module.exports = {
async headers() {
return [
{
source: '/blog/:post(\\d{1,})',
headers: [
{
key: 'x-post',
value: ':post',
},
],
},
]
},
}Следующие символы (, ), {, }, :, *, +, ? используются для сопоставления путей с регулярными выражениями, поэтому при использовании в source в качестве неспециальных значений они должны быть экранированы, добавив \\ перед ними:
module.exports = {
async headers() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
headers: [
{
key: 'x-header',
value: 'value',
},
],
},
]
},
}Сопоставление заголовков, куки и параметров запроса
Чтобы применить заголовок только тогда, когда значения заголовка, куки или параметров запроса также соответствуют полю has или не соответствуют полю missing, можно использовать это. И поле source, и все элементы has должны соответствовать, а все элементы missing — не соответствовать, для того чтобы заголовок был применен.
Элементы has и missing могут иметь следующие поля:
type:String— должно бытьheader,cookie,host, илиquery.key:String— ключ из выбранного типа для сопоставления.value:Stringилиundefined— значение для проверки. Если неопределено, то любое значение будет соответствовать. Можно использовать регулярное выражение в виде строки, чтобы захватить определённую часть значения, например, если значениеfirst-(?<paramName>.*)используется дляfirst-second, тоsecondбудет пригодно в пункте назначения с: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
При использовании поддержки basePath с заголовками каждый source автоматически предваряется basePath, если вы не добавите basePath: false к заголовку:
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
При использовании поддержки i18n с заголовками каждый source автоматически добавляется для обработки конфигурированной locales, если вы не добавите locale: false к заголовку. Если используется locale: false, вы должны добавить префикс source с локалью, чтобы он корректно сопоставлялся.
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.config.js для страниц или ресурсов, так как эти заголовки будут перезаписаны в производстве, чтобы обеспечить эффективное кэширование ответов и статических ресурсов.
Дополнительные сведения о кэшировании с помощью App Router.
Настройки
CORS
Cross-Origin Resource Sharing (CORS) — это функция безопасности, которая позволяет контролировать, какие сайты могут получить доступ к вашим ресурсам. Вы можете установить заголовок Access-Control-Allow-Origin для разрешения определённому источнику доступа к вашим обработчикам маршрутов.
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-Prefetch-Control
Этот заголовок управляет предварительной загрузкой DNS, позволяя браузерам предварительно выполнять разрешение доменных имён внешних ссылок, изображений, CSS, JavaScript и т. д. Эта предварительная загрузка выполняется в фоновом режиме, поэтому DNS скорее всего будет разрешён к моменту необходимости использования ссылок. Это уменьшает время ожидания при нажатии на ссылку.
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
}
Strict-Transport-Security
Этот заголовок сообщает браузерам, что к нему следует обращаться только с помощью HTTPS, а не HTTP. Используя приведенную ниже конфигурацию, все текущие и будущие поддомены будут использовать HTTPS в течение max-age 2 лет. Это блокирует доступ к страницам или поддоменам, которые могут быть доступны только по HTTP.
Если вы развертываете на Vercel, этот заголовок не требуется, поскольку он автоматически добавляется ко всем развертываниям, если вы не объявите headers в вашем next.config.js.
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}
X-Frame-Options
Этот заголовок указывает, разрешено ли отображать сайт в iframe. Это может предотвратить атаки с использованием clickjacking.
Этот заголовок был заменён опцией CSP frame-ancestors, которая имеет лучшую поддержку в современных браузерах (см. Политику безопасности содержимого для получения информации о конфигурации).
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
}
Permissions-Policy
Этот заголовок позволяет управлять функциональными возможностями и API, которые могут использоваться в браузере. Ранее он назывался Feature-Policy.
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}
X-Content-Type-Options
Этот заголовок предотвращает попытку браузера угадать тип содержимого, если заголовок Content-Type не установлен явно. Это может предотвратить атаки XSS для сайтов, которые позволяют пользователям загружать и делиться файлами.
Например, пользователь пытается загрузить изображение, но оно обрабатывается как другой Content-Type , например, исполняемый файл, который может быть вредоносным. Этот заголовок также применяется к загрузке расширений браузера. Единственное допустимое значение для этого заголовка — nosniff.
{
key: 'X-Content-Type-Options',
value: 'nosniff'
}
Referrer-Policy
Этот заголовок управляет количеством информации, которое браузер включает при переходе с текущего сайта (источника) на другой.
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
Политика безопасности содержимого
Дополнительные сведения о добавлении Политики безопасности содержимого в ваше приложение.
История версий
| Версия | Изменения |
|---|---|
v13.3.0 |
missing добавлено. |
v10.2.0 |
has добавлено. |
v9.5.0 |
Добавлены заголовки. |
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/app/api-reference/next-config-js/headers