Vercel Functions 地理定位实战:在 Edge 和 Serverless 中获取用户位置

主题: vercel-edge-middleware-geolocation更新于: 2026/7/4作者:AgentFactory 技术团队

@vercel/functions 包提供了 geolocation()ipAddress() 两个核心函数,让你在 Vercel 部署的应用中零配置获取用户地理位置和 IP 地址。本文聚焦安装、配置、参数详解和常见坑点,帮你快速在生产环境中落地。

安装与快速上手

安装

BASH
npm install @vercel/functions

基础用法(Next.js App Router 示例)

TYPESCRIPT
import { geolocation, ipAddress } from '@vercel/functions';

export async function GET(request: Request) {
  const geo = geolocation(request);
  const ip = ipAddress(request);

  return Response.json({
    city: geo.city,
    country: geo.country,
    region: geo.region,
    latitude: geo.latitude,
    longitude: geo.longitude,
    ip,
  });
}

关键点

  • geolocation()ipAddress() 都需要传入标准的 Request 对象。
  • 在 Next.js Pages Router 中,使用 req 对象(IncomingMessage 类型)同样有效。
  • 返回的 geo 对象中,cityregion 等字段可能为 undefined,务必做空值检查。

核心参数说明

参数类型必填说明
geolocation(request)Request返回 { city, country, latitude, longitude, region } 对象
ipAddress(request)Request返回请求的 IP 地址字符串

返回值字段详解

字段示例值说明
city"Beijing"城市名,可能为 undefined
country"CN"ISO 3166-1 alpha-2 国家代码
latitude"39.9042"纬度(字符串)
longitude"116.4074"经度(字符串)
region"iad1"Vercel Edge 节点代码,非用户所在地区

注意region 字段返回的是处理请求的 Vercel 边缘节点位置(如 hkg1 表示香港节点),并非用户的地理区域。如需用户所在地区(如 US-CA),需通过请求头 X-Vercel-IP-Country-Region 手动解析。

在 Edge Middleware 中集成(低延迟方案)

Edge Middleware 运行在 Vercel Edge Network,延迟极低,适合做基于地理位置的请求拦截或重定向。

TYPESCRIPT
// middleware.ts(项目根目录或 src/ 下)
import { geolocation } from '@vercel/functions';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const { country } = geolocation(request);

  // 限制非中国地区访问
  if (country !== 'CN') {
    return NextResponse.redirect(new URL('/blocked', request.url));
  }

  // 根据国家做 A/B 测试
  if (country === 'US') {
    return NextResponse.rewrite(new URL('/us-version', request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/api/:path*',
};

性能对比

方案延迟适用场景
Edge Middleware< 10ms重定向、A/B 测试、访问控制
Serverless Functions50-200ms需要数据库查询或复杂计算

与自建 IP 地理定位方案对比

维度Vercel Functions自建(MaxMind GeoIP2)
部署复杂度零配置,开箱即用需维护 IP 库更新、数据库查询
延迟Edge 层直接读请求头,极低可能涉及外部 API 或数据库查询
成本包含在 Vercel 平台费用中IP 库许可费或 API 调用费
精度国家、地区、城市级别可提供邮编、时区等更细粒度
可移植性绑定 Vercel 平台可迁移至任意云或本地

常见报错与排查

1. geolocation is not defined

原因:未正确导入或安装包。

解决

BASH
npm install @vercel/functions

确保导入语句正确:

TYPESCRIPT
import { geolocation } from '@vercel/functions';

TypeScript 用户需在 tsconfig.json 中设置 "esModuleInterop": true

2. Request object is not valid

原因:传入的参数不是标准的 Request 对象。

解决:在 Next.js App Router 中,从路由处理函数参数获取 request;在 Pages Router 中使用 req。不要传入 undefined 或自定义对象。

3. Geolocation headers are missing

原因:本地开发环境没有地理定位请求头。

解决

  • 使用 vercel dev 命令启动本地开发(Vercel CLI)。
  • 手动模拟请求头进行测试:
    BASH
    curl -H "X-Vercel-IP-Country: US" http://localhost:3000/api/geo
    
  • 生产环境若仍缺失,检查是否使用了代理(如 Cloudflare)。Enterprise 用户可启用 Trusted Proxy 功能。

4. Cannot read properties of undefined (reading 'city')

原因geolocation() 返回的对象中某些字段为 undefined

解决:访问前做空值检查:

TYPESCRIPT
const { city } = geolocation(request) || {};
// 或使用可选链
city?.toLowerCase();

常见问题 FAQ

Q: 如何在 Next.js 的 Edge Middleware 中使用 geolocation?

A: 在 middleware.ts 中直接调用 geolocation(request) 即可。注意:

  • middleware.ts 必须放在项目根目录或 src/ 目录下。
  • Edge Middleware 运行在 Vercel Edge Network,延迟极低,适合做重定向和访问控制。
  • 示例见上文“在 Edge Middleware 中集成”章节。

Q: geolocation() 返回的 region 字段是什么格式?

A: region 字段返回的是 Vercel Edge 节点代码(如 iad1hkg1),代表处理请求的边缘节点位置,并非用户的地理区域。如需用户所在地区(如 US-CA),需通过请求头 X-Vercel-IP-Country-Region 手动获取,geolocation() 函数目前不直接返回此字段。

Q: 能否在 Vercel Functions(Serverless)中使用 geolocation?

A: 可以。geolocation() 同时支持 Edge Middleware 和 Serverless Functions。在 Serverless 函数中,请求对象同样包含地理定位请求头。但注意:

  • Serverless 函数可能运行在特定区域,延迟比 Edge Middleware 高。
  • 建议对延迟敏感的场景(如重定向、A/B 测试)使用 Edge Middleware,对需要复杂计算或数据库操作的场景使用 Serverless Functions。

生产环境注意事项

  1. 代理问题:如果使用了 Cloudflare、自定义反向代理等,Vercel 无法获取正确的客户端 IP 和地理位置。Enterprise 用户可配置 Trusted Proxy 功能。
  2. 精度限制:Vercel 仅提供国家、地区、城市级别的地理位置,无法获取精确坐标或邮编。数据基于 IP 库,VPN 或代理可能导致误判。
  3. 配额限制:免费版 Vercel 账户对 Edge Middleware 的请求量有限制,高流量场景需注意配额。
  4. 无内置缓存:每次请求都需解析请求头,可能增加 Edge 函数执行时间。如需缓存,可在应用层自行实现。
  5. 安全性:地理位置信息通过请求头传递,确保不泄露给客户端或第三方。不要在客户端 JavaScript 中暴露这些数据。

相关深度解决方案

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Upstash Redis Serverless REST API 实战:从 HTTP 调用到 MCP 集成

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Next.js SSG 与同类方案怎么选:实测对比与选型指南