英文:
Next js api ip address return server ip not client ip
问题
I understand your request. Here's the translated code portion:
我正在使用Next.js应用程序,尝试获取客户端用户的IP地址和地理位置,但我得到的是我部署在`vercel`服务器上的IP地址。
我尝试了中间件:
```javascript
import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest, _next: NextFetchEvent) {
const { nextUrl: url, geo } = request
const country = geo?.country
// 克隆请求头并设置新的头部`x-hello-from-middleware1`
const requestHeaders = new Headers(request.headers)
requestHeaders.set('country', country || 'EG')
// 你也可以在NextResponse.rewrite中设置请求头
const response = NextResponse.next({
request: {
// 新的请求头
headers: requestHeaders,
},
})
return response
}
然后,在api
目录中使用来自头部的country
:
export default async (req: MyRequest, res: NextApiResponse) => {
if (req.method === 'GET') {
const country = req.headers.country;
}
}
我得到了服务器的国家信息!
我还尝试了:
export default async (req: MyRequest, res: NextApiResponse) => {
if (req.method === 'GET') {
const forwarded = req.headers['x-forwarded-for'];
const ip = typeof forwarded === 'string' ? forwarded.split(/, /)[0] : req.socket.remoteAddress;
}
}
但结果相同!主机服务器的IP地址。
为什么?有什么解决方法?
<details>
<summary>英文:</summary>
I'm using a Next js application, I'm trying to get the IP address and geolocation of the client user, but I got the id address of the `vercel` server that I deployed on.
I tried `middleware`:
import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest, _next: NextFetchEvent) {
const { nextUrl: url, geo } = request
const country = geo?.country
// Clone the request headers and set a new header `x-hello-from-middleware1`
const requestHeaders = new Headers(request.headers)
requestHeaders.set('country', country||'EG')
// You can also set request headers in NextResponse.rewrite
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
})
return response
}
then, when using `country` from header in `api` directory:
export default async (req:MyRequest, res:NextApiResponse) => {
if (req.method === 'GET') {
const country= req.headers.country;
}
}
I got server's country !!
I also tried:
export default async (req:MyRequest, res:NextApiResponse) => {
if (req.method === 'GET') {
const forwarded = req.headers['x-forwarded-for'];
const ip = typeof forwarded === 'string' ? forwarded.split(/, /)[0] : req.socket.remoteAddress;
}
}
But it's the same result! the ip of the hosting server.
Why?! and what's the solution?
</details>
# 答案1
**得分**: 1
> 当客户端直接连接到服务器时,客户端的IP地址会发送给服务器(通常会记录在服务器访问日志中)。
> 但是,如果客户端连接经过任何正向或反向代理,服务器只会看到最终代理的IP地址,这通常没有太大用处。
> 如果最终代理是服务器相同安装中的负载均衡器,这一点尤其如此。
我认为问题要么是您正在使用代理,要么是Vercel正在使用负载均衡器。`NextRequest`具有`ip`方法,请尝试使用:
```javascript
const ip = req.ip ?? "127.0.0.1";
英文:
> When a client connects directly to a server, the client's IP address
> is sent to the server (and is often written to server access logs).
> But if a client connection passes through any forward or reverse
> proxies, the server only sees the final proxy's IP address, which is
> often of little use. That's especially true if the final proxy is a
> load balancer which is part of the same installation as the server.
I think the problem is either you are using proxy or vercel is using a load balancer. NextRequest
has ip
method. try to use
const ip = req.ip ?? "127.0.0.1";
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论