本文详解在 Next.js 中不依赖 window.location.href 或 React Router 获取当前 URL 的最佳实践,涵盖服务端渲染(getServerSideProps)和客户端路由(useRouter)两种核心方案,并提供代码示例与关键注意事项。
本文详解在 next.js 中不依赖 `window.location.href` 或 react router 获取当前 url 的最佳实践,涵盖服务端渲染(getserversideprops)和客户端路由(userouter)两种核心方案,并提供代码示例与关键注意事项。
在 Next.js 应用中,直接访问 window.location.href 会引发服务端渲染(SSR)错误,因为 window 对象仅在浏览器环境中存在。为确保应用在 SSR、静态生成(SSG)及客户端路由切换时均能可靠获取当前 URL,必须根据执行环境选择合适的方法。
✅ 服务端场景:使用 getServerSideProps 获取完整请求上下文
当需要在页面首次渲染前获取原始请求 URL(如用于 SEO、权限校验或动态重定向),应利用 getServerSideProps 的 context 参数。它提供了完整的 Node.js HTTP 请求对象(req),可安全读取主机、协议、路径及查询参数:
// pages/example.tsx
export const getServerSideProps = async (context) => {
const { req } = context;
const { origin, href, pathname, query } = new URL(
req.url || '',
`${req.headers['x-forwarded-proto'] || 'http'}://${req.headers.host}`
);
return {
props: {
fullUrl: href, // 如 https://example.com/blog?id=123
origin, // 如 https://example.com
pathname, // 如 /blog
query // 如 { id: '123' }
}
};
};
export default function ExamplePage({ fullUrl, origin, pathname, query }) {
return (
<div>
<h2>服务端解析的 URL 信息</h2>
<p>完整地址:<code>{fullUrl}</code></p>
<p>根域名:<code>{origin}</code></p>
<p>路径:<code>{pathname}</code></p>
<p>查询参数:<code>{JSON.stringify(query)}</code></p>
</div>
);
}⚠️ 注意事项:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- req.url 默认为相对路径(如 /blog?id=123),需手动拼接 origin 才能得到绝对 URL;
- 若部署在反向代理(如 Nginx、Vercel)后,务必通过 x-forwarded-proto 和 host 头构造正确协议与域名;
- 此方法仅适用于页面级数据获取(pages 目录),不适用于组件内部。
✅ 客户端场景:使用 useRouter 获取路由状态
对于交互式操作(如点击按钮复制当前路径、根据路由动态更新 UI),推荐使用 Next.js 内置的 useRouter Hook。它在客户端完全可用,且支持实时响应路由变化:
// components/CurrentPathDisplay.tsx
'use client'; // 必须声明为客户端组件(App Router 下)
import { useRouter } from 'next/navigation';
export default function CurrentPathDisplay() {
const router = useRouter();
const { pathname, query } = router;
return (
<div>
<h3>当前客户端路由</h3>
<p>路径:<code>{pathname}</code></p>
<p>查询参数:<code>{JSON.stringify(query)}</code></p>
<button
onClick={() => navigator.clipboard.writeText(window.location.href)}
className="mt-2 px-3 py-1 bg-blue-500 text-white rounded"
>
复制完整 URL
</button>
</div>
);
}? 提示:
- useRouter 返回的 pathname 不含查询参数,query 是解析后的对象(字符串值自动解码);
- 在 App Router(app/ 目录)中,使用 next/navigation 的 useRouter;在 Pages Router(pages/ 目录)中,使用 next/router;
- 若需完整 URL 字符串(含协议、域名),仍可安全使用 window.location.href —— 但仅限客户端组件内且确保已挂载(可通过 useEffect 或 typeof window !== 'undefined' 判断)。
? 总结:按需选择,避免常见陷阱
| 场景 | 推荐方案 | 是否 SSR 安全 | 可获取内容 |
|---|---|---|---|
| 页面初始数据(如 SEO、鉴权) | getServerSideProps + context.req | ✅ 是 | 原始请求 URL、headers、IP 等 |
| 客户端交互与路由监听 | useRouter | ❌ 否(仅客户端) | pathname、query、asPath(带 hash) |
| 需要绝对 URL 字符串(客户端) | window.location.href(配合 'use client' 和挂载检查) | ❌ 否 | 完整浏览器地址栏 URL |
切勿在服务端组件或 getStaticProps 中尝试访问 window,也避免滥用第三方 URL 解析库(如 url-parse)替代原生 URL 构造函数——Next.js 运行时已提供标准 Web API 支持,简洁、安全、无需额外依赖。

















