標頭主要使用路由模組 headers
export 定義。您也可以在 entry.server.tsx
中設定標頭。
import { Route } from "./+types/some-route";
export function headers(_: Route.HeadersArgs) {
return {
"Content-Security-Policy": "default-src 'self'",
"X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff",
"Cache-Control": "max-age=3600, s-maxage=86400",
};
}
您可以傳回 Headers
實例或 HeadersInit
。
當標頭取決於 loader 資料時,loaders 和 actions 也可以設定標頭。
data
中import { data } from "react-router";
export async function loader({ params }: LoaderArgs) {
let [page, ms] = await fakeTimeCall(
await getPage(params.id)
);
return data(page, {
headers: {
"Server-Timing": `page;dur=${ms};desc="Page query"`,
},
});
}
headers
export 傳回來自 loaders 和 actions 的標頭不會自動傳送。您必須從 headers
export 明確地傳回它們。
export function headers({
actionHeaders,
loaderHeaders,
}: HeadersArgs) {
return actionHeaders ? actionHeaders : loaderHeaders;
}
一個值得注意的例外是 Set-Cookie
標頭,即使沒有從子路由 export headers
,它們也會自動從父路由的 headers
、loader
和 action
中保留。
考慮這些巢狀路由
route("pages", "pages-layout-with-nav.tsx", [
route(":slug", "page.tsx"),
]);
如果兩個路由模組都想要設定標頭,則將傳送最深層匹配路由的標頭。
當您需要同時保留父層和子層標頭時,您需要在子路由中合併它們。
最簡單的方法是簡單地附加到父層標頭。這避免了覆寫父層可能已設定的標頭,並且兩者都很重要。
export function headers({ parentHeaders }: HeadersArgs) {
parentHeaders.append(
"Permissions-Policy: geolocation=()"
);
return parentHeaders;
}
有時覆寫父層標頭很重要。請使用 set
而不是 append
來執行此操作
export function headers({ parentHeaders }: HeadersArgs) {
parentHeaders.set(
"Cache-Control",
"max-age=3600, s-maxage=86400"
);
return parentHeaders;
}
您可以透過僅在「葉路由」(索引路由和沒有子路由的子路由)中定義標頭,而不在父路由中定義標頭,來避免合併標頭的需求。
entry.server.tsx
handleRequest
export 接收來自路由模組的標頭作為參數。您可以在此處附加全域標頭。
export default function handleRequest(
request,
responseStatusCode,
responseHeaders,
routerContext,
loadContext
) {
// set, append global headers
responseHeaders.set(
"X-App-Version",
routerContext.manifest.version
);
return new Response(await getStream(), {
headers: responseHeaders,
status: responseStatusCode,
});
}
如果您沒有 entry.server.tsx
,請執行 reveal
命令
react-router reveal