headers
透過 headers 可以在指定路徑對傳入請求的響應設定自定義 HTTP 頭部。
要設定自定義 HTTP 頭部,可以在 next.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 是一個非同步函式,需要返回一個數組,其中包含帶有 source 和 headers 屬性的物件。
source是傳入請求的路徑模式。headers是一個響應頭部物件陣列,具有key和value屬性。basePath:false或undefined- 如果為 false,則在匹配時不包含 basePath,僅可用於外部重寫。locale:false或undefined- 匹配時是否不包含 locale。has是一個具有type、key和value屬性的 has 物件陣列。missing是一個具有type、key和value屬性的 missing 物件陣列。
頭部檢查優先於檔案系統,包括頁面和 /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',
},
],
},
]
},
}標頭、Cookie 和查詢匹配
只有當頭部、cookie 或查詢值也與 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.js 為真正不可變的資產設定 public, max-age=31536000, immutable 的 Cache-Control 頭部。它無法被覆蓋。這些不可變檔案在檔名中包含 SHA 雜湊,因此可以安全地無限期快取。例如,靜態圖片匯入。你無法在 next.config.js 中為這些資產設定 Cache-Control 頭部。
但是,你可以為其他響應或資料設定 Cache-Control 頭部。
如果你需要重新驗證已 靜態生成 的頁面的快取,可以透過在頁面的 getStaticProps 函式中設定 revalidate 屬性來完成。
要快取 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!' })
}你還可以在 getServerSideProps 中使用快取頭部 (Cache-Control) 來快取動態響應。例如,使用 stale-while-revalidate。
import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next'
// This value is considered fresh for ten seconds (s-maxage=10).
// If a request is repeated within the next 10 seconds, the previously
// cached value will still be fresh. If the request is repeated before 59 seconds,
// the cached value will be stale but still render (stale-while-revalidate=59).
//
// In the background, a revalidation request will be made to populate the cache
// with a fresh value. If you refresh the page, you will see the new value.
export const getServerSideProps = (async (context) => {
context.res.setHeader(
'Cache-Control',
'public, s-maxage=10, stale-while-revalidate=59'
)
return {
props: {},
}
}) satisfies GetServerSideProps選項
CORS
跨域資源共享 (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。使用以下配置,所有當前和未來的子域名將在 2 年的 max-age 內使用 HTTPS。這會阻止訪問只能透過 HTTP 提供的頁面或子域名。
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}X-Frame-Options
此頭部 指示站點是否允許在 iframe 中顯示。這可以防止點選劫持攻擊。
此頭部已被 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'
}Content-Security-Policy
瞭解有關嚮應用程式新增內容安全策略的更多資訊。
版本歷史
| 版本 | 更改 |
|---|---|
v13.3.0 | missing 已新增。 |
v10.2.0 | has 已新增。 |
v9.5.0 | 標頭已新增。 |
這有幫助嗎?