Blitz 尚在 beat 阶段! 🎉 预计会在今年的 Q3 季度发布 1.0
Back to Documentation Menu

HTTP Headers

Topics

Jump to a Topic

Headers 允许你为传入的请求路径设置自定义 HTTP 头部。

要设置自定义 HTTP 头部,你可以使用 blitz.config.js 中的 headers 键:

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 属 性的对象的数组:

  • source 是传入的请求路径模式。
  • headers 是一个带有 keyvalue 属性的 header 对象数组。
  • basePath: falseundefined - 如果为 false,匹配时将不包含 basePath,只能用于外部重写。
  • locale: falseundefined - 匹配时是否不应该包含语言环境。
  • has 是具有 typekeyvalue 属性的 has 对象 数组。

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

Header 覆盖行为

如果两个 header 匹配相同的路径并设置相同的 header 键,则最后一个 header 键 将覆盖第一个。使用下方的 header 文件,路径 hello 将导致 header 文件 x-helloworld,因为最后一个 header 文件值设置为 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', // 可以再值中使用匹配到的参数
          },
          {
            key: 'x-slug-:slug', // 可以在键中使用匹配到的参数
            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*', // 可以再值中使用匹配到的参数
          },
          {
            key: 'x-slug-:slug*', // 可以在键中使用匹配到的参数
            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 redirects() {
    return [
      {
        // 这将匹配正在请求的 `/english(default)/something`
        source: "/english\\(default\\)/:slug",
        destination: "/en-us/:slug",
        permanent: false,
      },
    ]
  },
}

仅当 header、cookie 或查询值也与 has 字段匹配时才应用 header。 source 和所有 has 项都必须匹配才能使用 header。

has 项具有以下字段:

  • typeString - 必须是 headercookiehostquery
  • key: String - 所选类型中要匹配的键。
  • valueStringundefined——要检查的值,如果未定义任何值将匹配。像 字符串这样的正则表达式可用于捕获值的特定部分,例如如果值 first-(?<paramName>.*) 用于 first-second,那么 second 将在目的路径 中使用 :paramName
module.exports = {
  async headers() {
    return [
      // 如果 header `x-add-header` 存在,
      // 则将使用 `x-another-header` header
      {
        source: "/:path*",
        has: [
          {
            type: "header",
            key: "x-add-header",
          },
        ],
        headers: [
          {
            key: "x-another-header",
            value: "hello",
          },
        ],
      },
      // 若果源、查询和 cookie 匹配,
      // 则将使用 `x-authorized` header
      {
        source: "/specific/:path*",
        has: [
          {
            type: "query",
            key: "page",
            // 页面值在 header 键/值中不可用,因为提供了值并且不使用命名的捕获组,例如(?<page>home)
            value: "home",
          },
          {
            type: "cookie",
            key: "authorized",
            value: "true",
          },
        ],
        headers: [
          {
            key: "x-authorized",
            value: ":authorized",
          },
        ],
      },
      // 如果 header `x-authorized` 存在且
      // 包含匹配到的值,则使用 `x-another-header`
      {
        source: "/:path*",
        has: [
          {
            type: "header",
            key: "x-authorized",
            value: "(?<authorized>yes|true)",
          },
        ],
        headers: [
          {
            key: "x-another-header",
            value: ":authorized",
          },
        ],
      },
      // 如果域名是 `example.com`,
      // 则将使用此 header
      {
        source: "/:path*",
        has: [
          {
            type: "host",
            value: "example.com",
          },
        ],
        headers: [
          {
            key: "x-another-header",
            value: ":authorized",
          },
        ],
      },
    ]
  },
}

使用 basePath 支持 Headers

当利用 basePath 支持 和 header 时,每个 source 都会自动以 basePath 为前缀,除非你将 basePath: false 添加到 header:

module.exports = {
  basePath: "/docs",

  async headers() {
    return [
      {
        source: "/with-basePath", // 变为 /docs/with-basePath
        headers: [
          {
            key: "x-hello",
            value: "world",
          },
        ],
      },
      {
        source: "/without-basePath", // 未修改,因为 basePath: false 被设置
        headers: [
          {
            key: "x-hello",
            value: "world",
          },
        ],
        basePath: false,
      },
    ]
  },
}

使用 i18n 支持 Headers

当利用带有 header 的 i18n 支持 时,每个 source 都会 自动添加前缀来处理配置的 locales,除非你将 locale: false 添加到 header 中。 如果使用 locale: false,你必须在 source 前面加上一个区域设置,才 能正确匹配。

module.exports = {
  i18n: {
    locales: ["en", "fr", "de"],
    defaultLocale: "en",
  },

  async headers() {
    return [
      {
        source: "/with-locale", // 自动处理所有 locales
        headers: [
          {
            key: "x-hello",
            value: "world",
          },
        ],
      },
      {
        // 不自动处理 locales,因为 locale: false 被设置
        source: "/nl/with-locale-manual",
        locale: false,
        headers: [
          {
            key: "x-hello",
            value: "world",
          },
        ],
      },
      {
        // 将匹配 '/' 因为 `en` 是 defaultLocale
        source: "/en",
        locale: false,
        headers: [
          {
            key: "x-hello",
            value: "world",
          },
        ],
      },
      {
        // 这被转换为 /(en|fr|de)/(.*) 所以不会像 /:path*
        // 这样地匹配顶级 `/` 或 `/fr` 路由
        source: "/(.*)",
        headers: [
          {
            key: "x-hello",
            value: "worlld",
          },
        ],
      },
    ]
  },
}

缓存控制

在 blitz.config.js 中设置的 Cache-Control header 将在生产中被覆盖,以确保 可以有效地缓存静态资产。如果你需要重新验证已 经静态生成的页面的缓存,你可以通 过页面中的 getStaticProps 函数。


Idea for improving this page? Edit it on GitHub.