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 — если 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

Spec-Zone.ru

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