You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:35:35