如何将Next.js中间件中的请求数据传递至页面组件?
在Next.js中传递中间件的IP与Geo数据到页面组件
有两种常用方式可以实现这个需求,具体如下:
方法一:通过自定义请求头传递
在中间件里把IP和Geo数据添加到请求头,再在getServerSideProps中读取这些头信息,最终传递给页面组件。
修改中间件代码
import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server' export function middleware(req: NextRequest) { const { ip, geo } = req; const response = NextResponse.next(); // 将IP和Geo数据存入请求头(Geo需序列化为字符串) if (ip) { response.headers.set('X-User-IP', ip); } if (geo) { response.headers.set('X-User-Geo', JSON.stringify(geo)); } return response; } export const config = { matcher: '/' }
修改首页组件的getServerSideProps
import type { NextPage, GetServerSideProps } from "next" interface HomeProps { userIp?: string; userGeo?: { country?: string; city?: string; latitude?: number; longitude?: number; region?: string; }; } const Home: NextPage<HomeProps> = ({ userIp, userGeo }) => { return ( <div> <p>你的IP:{userIp}</p> <p>所在国家:{userGeo?.country}</p> <p>所在城市:{userGeo?.city}</p> </div> ); }; export default Home; export const getServerSideProps: GetServerSideProps<HomeProps> = async (context) => { // 从请求头读取数据并解析 const userIp = context.req.headers['x-user-ip'] as string; const userGeoStr = context.req.headers['x-user-geo'] as string; const userGeo = userGeoStr ? JSON.parse(userGeoStr) : undefined; return { props: { userIp, userGeo } } }
方法二:通过Cookie传递
如果需要数据在客户端也能访问,可以选择把数据存入Cookie,再在getServerSideProps中读取。
修改中间件代码
import type { NextRequest } from 'next/server'; import { NextResponse } from 'next/server' export function middleware(req: NextRequest) { const { ip, geo } = req; const response = NextResponse.next(); // 将IP和Geo数据存入Cookie if (ip) { response.cookies.set('user-ip', ip); } if (geo) { response.cookies.set('user-geo', JSON.stringify(geo)); } return response; } export const config = { matcher: '/' }
修改首页组件的getServerSideProps
import type { NextPage, GetServerSideProps } from "next" interface HomeProps { userIp?: string; userGeo?: { country?: string; city?: string; latitude?: number; longitude?: number; region?: string; }; } const Home: NextPage<HomeProps> = ({ userIp, userGeo }) => { return ( <div> <p>你的IP:{userIp}</p> <p>所在国家:{userGeo?.country}</p> <p>所在城市:{userGeo?.city}</p> </div> ); }; export default Home; export const getServerSideProps: GetServerSideProps<HomeProps> = async (context) => { // 从Cookie读取数据并解析 const userIp = context.req.cookies['user-ip']; const userGeoStr = context.req.cookies['user-geo']; const userGeo = userGeoStr ? JSON.parse(userGeoStr) : undefined; return { props: { userIp, userGeo } } }
注意事项
- 请求头建议用
X-前缀,避免和标准HTTP头冲突; - Geo是复杂对象,必须用
JSON.stringify序列化为字符串才能存入头或Cookie,读取时再用JSON.parse解析; - 使用Cookie时要注意单个Cookie的大小限制(不超过4KB),确保Geo数据不会超出上限。
内容的提问来源于stack exchange,提问作者Md Ali
相关产品推荐
相关产品推荐

