Next.js 13服务端渲染(SSR)中如何获取URL?
Next.js 13 获取URL的解决方案
问题根源是window是浏览器专属API,服务端渲染阶段不存在,直接调用会触发window未定义错误。下面分两种路由方案给出对应解决思路:
App Router(Next.js 13+ 主推)
1. 客户端组件中获取URL
客户端组件在浏览器环境运行,可以安全使用window,但注意不要在组件顶层直接调用(避免服务端预渲染报错),推荐两种写法:
- 用useEffect延迟执行
'use client'; import { useEffect, useState } from 'react'; export default function ClientPage() { const [fullUrl, setFullUrl] = useState(''); useEffect(() => { setFullUrl(window.location.href); }, []); return <div>当前URL:{fullUrl}</div>; }
- 用类型判断做兼容
'use client'; export default function ClientPage() { const fullUrl = typeof window !== 'undefined' ? window.location.href : ''; return <div>当前URL:{fullUrl}</div>; }
如果需要获取路径、查询参数等细分内容,可以用next/navigation提供的usePathname和useSearchParams钩子:
'use client'; import { usePathname, useSearchParams } from 'next/navigation'; export default function ClientPage() { const pathname = usePathname(); const searchParams = useSearchParams(); const fullUrl = typeof window !== 'undefined' ? `${window.location.origin}${pathname}${searchParams.toString() ? `?${searchParams.toString()}` : ''}` : ''; return <div>当前URL:{fullUrl}</div>; }
2. 服务端组件中获取URL
服务端组件无法访问window,需要通过headers()函数读取请求头信息拼接完整URL:
import { headers } from 'next/headers'; export default function ServerPage() { const headersList = headers(); // 协议:优先取反向代理传递的x-forwarded-proto,本地开发默认http const protocol = headersList.get('x-forwarded-proto') || 'http'; // 域名+端口 const host = headersList.get('host'); // 当前路径(包含查询参数) const path = headersList.get('next-url'); const fullUrl = `${protocol}://${host}${path}`; return <div>服务端获取的URL:{fullUrl}</div>; }
Pages Router(Next.js 13 仍兼容)
1. 客户端页面/组件中获取URL
和App Router客户端组件逻辑一致,也可以用next/router的useRouter钩子:
import { useEffect, useState } from 'react'; import { useRouter } from 'next/router'; export default function ClientPage() { const router = useRouter(); const [fullUrl, setFullUrl] = useState(''); useEffect(() => { setFullUrl(`${window.location.origin}${router.asPath}`); }, [router.asPath]); return <div>当前URL:{fullUrl}</div>; }
2. 服务端渲染页面(getServerSideProps)中获取URL
通过getServerSideProps的上下文参数读取请求信息:
export async function getServerSideProps(context) { const { req } = context; const protocol = req.headers['x-forwarded-proto'] || 'http'; const host = req.headers.host; const fullUrl = `${protocol}://${host}${req.url}`; return { props: { fullUrl } }; } export default function ServerPage({ fullUrl }) { return <div>服务端获取的URL:{fullUrl}</div>; }
内容的提问来源于stack exchange,提问作者CatalinPCE
相关产品推荐
相关产品推荐

