Заголовки
Заголовки позволяют задавать пользовательские 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— если ложно, 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 для страниц или ресурсов, так как эти заголовки будут перезаписаны в производстве, чтобы гарантировать эффективное кэширование ответов и статических ресурсов.
Если вам нужно перепроверить кэш страницы, которая была статически сгенерирована, вы можете сделать это, установив свойство revalidate в функции getStaticProps страницы.
Вы можете установить заголовок Cache-Control в ваших маршрутах API, используя метод res.setHeader:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.setHeader('Cache-Control', 's-maxage=86400')
res.status(200).json({ message: 'Hello from Next.js!' })
}Параметры
CORS
Cross-Origin Resource Sharing (CORS) — это функция безопасности, которая позволяет контролировать, с каких сайтов можно получать доступ к вашим ресурсам. Вы можете установить заголовок Access-Control-Allow-Origin для разрешения определённому источнику доступа к вашим конечным точкам API.
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's 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/pages/api-reference/next-config-js/headers