Spec-Zone.ru › Next.js

Заголовки

Заголовки позволяют задавать пользовательские 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 Заголовки добавлены.
END_OF_DOCUMENT_MARKER

© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/pages/api-reference/next-config-js/headers

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API