如何在 Next.js 13 中获取客户端的 IP 地址?

Nus*_*b19 5 ip-address next.js next.js13

我有一个 next.js 13 应用程序,想要添加一个 API 端点/api/getIP

route.js文件位于/app/api/getIP/route.js.

最小可复制代码: https ://github.com/Nusab19/nextjs-test/tree/main/app

我尝试了几种方法,但没有一种有效。我尝试使用request-ip获取 ip 但它返回了null

这是我的代码:

import { NextResponse } from "next/server";
import requestIp from "request-ip";

export async function GET(req) {
  const detectedIp = requestIp.getClientIp(req);
  const data = {
    ok: true,
    ip: detectedIp,
    userAgent: req.headers.get("user-agent"),
  };
  return new NextResponse(JSON.stringify(data, null, 2));
}
Run Code Online (Sandbox Code Playgroud)

当我访问时我收到这样的回复:

{
    "ok": true,
    "ip": null,
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*mas 1

由于您已经在使用 Next.jsapp路由器,我假设您在 Vercel 上托管。

如果是,Vercel 可以使用Next.js 中间件提供这些信息。

ip:(字符串 || 未定义)- 具有请求的 IP 地址。此信息由您的托管平台提供。

https://nextjs.org/docs/pages/api-reference/functions/next-server#nextrequest

您可以通过在存储库的根目录下app创建文件(如果您使用的是,那么它应该是)来创建 Next.js中间件,其内容为:middleware.jssrc/appsrc/middleware.js

import { NextRequest, NextResponse } from 'next/server';

export async function middleware(req: NextRequest) {
  const { ip, nextUrl } = req;

  nextUrl.searchParams.set('clientIp', ip);

  return NextResponse.rewrite(nextUrl);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将添加clientIp作为查询参数,然后将其传递给您的路由处理程序。

在你的路由处理程序中,你可以像下面这样访问它:

export async function GET(req) {
  const data = {
    ok: true,
    ip: req.query?.clientIp ?? "127.0.0.1",
    message: "Hello from the API",
  };
  return new NextResponse(JSON.stringify(data, null, 2));
}
Run Code Online (Sandbox Code Playgroud)

缺点是,它无法在您的本地环境(无论如何您知道您的本地 IP)和任何不提供此信息的托管平台中工作。


如果您不想使用中间件,可以使用请求标头来检索 ip。

export async function GET(req) {
  const data = {
    ok: true,
    ip: req.headers.get("x-real-ip") ?? "127.0.0.1",
    message: "Hello from the API",
  };
  return new NextResponse(JSON.stringify(data, null, 2));
}
Run Code Online (Sandbox Code Playgroud)