如何在Next.js中结合getServerSideProps传递完整Geo对象
问题
我正在使用Next.js的Middleware功能,已创建Middleware文件并编写代码,成功通过URL查询参数传递country值,在首页借助getServerSideProps接收并展示。
Middleware代码:
import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' export function middleware(req: NextRequest) { const { nextUrl: url, geo } = req const country = geo?.country || 'US' url.searchParams.set('country', country) return NextResponse.rewrite(url) } export const config = { matcher: '/' }
首页代码:
export default function Home(props: any) { console.log(props) return ( <h1 className={styles.title}> Welcome to {props.country} </h1> ) } export const getServerSideProps = ({ query }: any) => ({ props: query, })
现在我想传递Middleware中geo对象包含的city、region、latitude、longitude、country全部字段到页面组件,尝试直接将geo对象设置为URL查询参数失败,请求指导实现方法。
失败的尝试代码:
import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' export function middleware(req: NextRequest) { const { nextUrl: url, geo } = req // 尝试传递完整geo对象而非仅country字符串 // 请求指导如何从这里传递对象到页面组件 url.searchParams.set('country', geo) return NextResponse.rewrite(url) } export const config = { matcher: '/' }
解决方案
方法1:逐个设置查询参数
直接遍历geo对象的属性,逐个添加到URL查询参数中,getServerSideProps可直接从query中获取每个字段。
修改后的Middleware代码:
import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' export function middleware(req: NextRequest) { const { nextUrl: url, geo } = req // 兜底默认值,避免geo为undefined const geoData = geo || { country: 'US', city: '', region: '', latitude: 0, longitude: 0 } // 遍历geo对象,添加所有有效字段到查询参数 Object.entries(geoData).forEach(([key, value]) => { if (value != null) { url.searchParams.set(key, String(value)) } }) return NextResponse.rewrite(url) } export const config = { matcher: '/' }
首页代码无需修改,getServerSideProps会自动把所有查询参数作为props传递给组件,此时props会包含city、region、latitude、longitude、country字段。
方法2:序列化geo对象为JSON字符串
如果字段较多,可将geo对象序列化为JSON字符串作为单个查询参数传递,在getServerSideProps中再解析。
Middleware代码:
import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' export function middleware(req: NextRequest) { const { nextUrl: url, geo } = req const geoData = geo || { country: 'US', city: '', region: '', latitude: 0, longitude: 0 } // 序列化geo对象为JSON字符串 const geoJson = JSON.stringify(geoData) url.searchParams.set('geo', geoJson) return NextResponse.rewrite(url) } export const config = { matcher: '/' }
修改首页的getServerSideProps解析JSON:
export default function Home(props: any) { console.log(props.geo) return ( <h1 className={styles.title}> Welcome to {props.geo.country}, {props.geo.city} </h1> ) } export const getServerSideProps = ({ query }: any) => { // 解析geo参数的JSON字符串 const geo = query.geo ? JSON.parse(query.geo) : { country: 'US' } return { props: { geo } } }
注意事项
- URL查询参数仅支持字符串类型,传递数字类型(如
latitude/longitude)时需转为字符串,接收时可再转回对应类型。 - 若
geo包含敏感信息,不建议用URL查询参数传递,可改用请求头传递,在getServerSideProps的req.headers中获取(注意请求头也会被客户端可见,敏感数据需谨慎)。
内容的提问来源于stack exchange,提问作者Md Ali
相关产品推荐
相关产品推荐

