getServerSideProps
如果您從頁面導出名為 getServerSideProps
(伺服器端渲染) 的函數,Next.js 將會在每次請求時使用 getServerSideProps
返回的資料預渲染此頁面。
import type { InferGetServerSidePropsType, GetServerSideProps } from 'next'
type Repo = {
name: string
stargazers_count: number
}
export const getServerSideProps = (async (context) => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}) satisfies GetServerSideProps<{
repo: Repo
}>
export default function Page({
repo,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return repo.stargazers_count
}
export async function getServerSideProps() {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}
export default function Page({ repo }) {
return repo.stargazers_count
}
請注意,無論渲染類型為何,任何
props
都會傳遞給頁面元件,並且可以在初始 HTML 的客戶端查看。這是為了讓頁面能夠正確地進行水合 (hydrate)。請確保不要在props
中傳遞任何不應在客戶端可用的敏感資訊。
getServerSideProps 何時執行
getServerSideProps
僅在伺服器端執行,從不在瀏覽器中執行。如果頁面使用了 getServerSideProps
,則:
- 當您直接請求此頁面時,
getServerSideProps
會在請求時執行,並且此頁面將使用返回的 props 進行預渲染 - 當您通過
next/link
或next/router
在客戶端頁面轉換中請求此頁面時,Next.js 會向伺服器發送 API 請求,該請求會執行getServerSideProps
getServerSideProps
返回的 JSON 將用於渲染頁面。所有這些工作都會由 Next.js 自動處理,因此只要您定義了 getServerSideProps
,就不需要做任何額外的事情。
您可以使用 next-code-elimination 工具 來驗證 Next.js 從客戶端套件中移除了哪些內容。
getServerSideProps
只能從頁面導出。您不能從非頁面文件中導出它。
請注意,您必須將 getServerSideProps
作為獨立函數導出 — 如果將 getServerSideProps
作為頁面元件的屬性添加,它將無法工作。
getServerSideProps
API 參考文件 涵蓋了可以與 getServerSideProps
一起使用的所有參數和 props。
何時應該使用 getServerSideProps
您應該僅在需要渲染其資料必須在請求時獲取的頁面時使用 getServerSideProps
。這可能是由於資料的性質或請求的屬性(例如 authorization
標頭或地理位置)。使用 getServerSideProps
的頁面將在請求時進行伺服器端渲染,並且只有在配置了 cache-control 標頭時才會被緩存。
如果您不需要在請求時渲染資料,則應考慮在客戶端 或使用 getStaticProps
獲取資料。
getServerSideProps 或 API 路由
當您想從伺服器獲取資料時,可能會想要使用 API 路由,然後從 getServerSideProps
調用該 API 路由。這是一種不必要且低效的方法,因為它會導致額外的請求,因為 getServerSideProps
和 API 路由都在伺服器上運行。
請看以下示例。API 路由用於從 CMS 獲取一些資料。然後直接從 getServerSideProps
調用該 API 路由。這會產生額外的調用,降低性能。相反,應直接將 API 路由中使用的邏輯導入 getServerSideProps
。這可能意味著直接在 getServerSideProps
內部調用 CMS、數據庫或其他 API。
與 Edge API 路由一起使用 getServerSideProps
getServerSideProps
可以與 Serverless 和 Edge 運行時 一起使用,並且您可以在兩者中設置 props。但是,目前在 Edge 運行時中,您無法訪問響應對象。這意味著您無法 — 例如 — 在 getServerSideProps
中添加 cookies。要訪問響應對象,您應繼續使用 Node.js 運行時,這是默認運行時。
您可以通過修改 config
在每個頁面的基礎上明確設置運行時,例如:
export const config = {
runtime: 'nodejs', // 或 "edge"
}
export const getServerSideProps = async () => {}
在客戶端獲取資料
如果您的頁面包含頻繁更新的資料,並且您不需要預渲染資料,則可以在客戶端 獲取資料。例如用戶特定的資料:
- 首先,立即顯示沒有資料的頁面。頁面的某些部分可以使用靜態生成進行預渲染。您可以為缺失的資料顯示加載狀態
- 然後,在客戶端獲取資料並在準備就緒時顯示
這種方法非常適合用戶儀表板頁面。因為儀表板是一個私有的、用戶特定的頁面,SEO 無關緊要,並且頁面不需要預渲染。資料頻繁更新,這需要在請求時獲取資料。
使用 getServerSideProps 在請求時獲取資料
以下示例顯示如何在請求時獲取資料並預渲染結果。
// 這會在每次請求時調用
export async function getServerSideProps() {
// 從外部 API 獲取資料
const res = await fetch(`https://.../data`)
const data = await res.json()
// 通過 props 將資料傳遞給頁面
return { props: { data } }
}
export default function Page({ data }) {
// 渲染資料...
}
使用伺服器端渲染 (SSR) 進行緩存
您可以在 getServerSideProps
中使用緩存標頭 (Cache-Control
) 來緩存動態響應。例如,使用 stale-while-revalidate
。
// 此值在十秒內被視為新鮮 (s-maxage=10)。
// 如果在接下來的 10 秒內重複請求,則之前緩存的值仍將是新鮮的。如果在 59 秒前重複請求,
// 緩存的值將是過時的但仍會渲染 (stale-while-revalidate=59)。
//
// 在後台,將發出重新驗證請求以用新值填充緩存。
// 如果您刷新頁面,您將看到新值。
export async function getServerSideProps({ req, res }) {
res.setHeader(
'Cache-Control',
'public, s-maxage=10, stale-while-revalidate=59'
)
return {
props: {},
}
}
了解更多關於緩存的資訊。
getServerSideProps 是否會渲染錯誤頁面
如果在 getServerSideProps
中拋出錯誤,它將顯示 pages/500.js
文件。查看 500 頁面 的文件以了解如何創建它。在開發過程中,此文件不會被使用,而是會顯示開發覆蓋層。