为啥 request.getRemoteAddr() 根据上下文返回 ipv4 或 ipv6(post 查询或 ajax 查询)

Posted

技术标签:

【中文标题】为啥 request.getRemoteAddr() 根据上下文返回 ipv4 或 ipv6(post 查询或 ajax 查询)【英文标题】:Why request.getRemoteAddr() returns ipv4 or ipv6 depending on context (post query or ajax query)为什么 request.getRemoteAddr() 根据上下文返回 ipv4 或 ipv6(post 查询或 ajax 查询) 【发布时间】:2011-03-08 07:47:16 【问题描述】:

我用 Spring/GWT 制作了一个使用 Flash 上传文件的网络应用程序。

当我使用 GWT 发送 ajax 请求并尝试获取用户 ip 地址时,我得到一个 ipv4 地址,例如:127.0.0.1

但是当我使用 flash 上传文件时(以及在同一个 webapp 上的发布请求)我得到一个 ipv6 地址 0:0:0:0:0:0:0:1

我使用相同的代码来获取用户 ip,即:

ServletRequestAttributes att = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
att.getRequest().getRemoteAddr();

问题是我使用了一个使用 ip 地址的签名来确保用户可以上传文件(由于使用 flash 上传时会话丢失的错误),并且当我使用 ajax 或通过 flash 发布时,ip 地址会发生变化。

什么问题,我怎样才能得到相同的ip格式?

谢谢

【问题讨论】:

您无法控制用户使用的 IP 地址,请尝试使用 cookie。 【参考方案1】:

您获得一个 IPv6 地址,然后使用 IPv6。 IPv4 和 IPv6 是不同的协议,当两者都可用时,客户端会选择使用哪一个。

如果您想要客户端的 IPv4 地址,则可以通过不在 DNS 中通告 IPv6 地址来强制他们使用它。尽管随着 IPv6 部署的增加,这将是一个坏主意。两者都支持很好,所以最好处理使用 IPv6 的客户端。

【讨论】:

【参考方案2】:

您可以通过使用此标志启动服务器来修复它

-Djava.net.preferIPv4Stack=true

【讨论】:

8 年后我改变了我接受的答案。因为它似乎对人们有更多帮助;)【参考方案3】:

原因是您在浏览器中输入的名称同时具有 ipv4 和 ipv6 地址。浏览器选择使用ipv4,flash选择使用ipv6。在服务器端对此您无能为力(无法转换)。 但是,您可以更改您的 DNS 并让您的名称只有一个地址,即 ipv4 或 ipv6。您还可以使用文字 IP 地址 (127.0.0.1) 而不是名称 (localhost) 进行连接。

【讨论】:

那么,如何识别用户?无需要求他更改各种设置。 您(客户端)使用的主机名是什么?是本地主机吗?它是真实的主机名吗? localhost(调试时为我)和真实主机名(真实客户端) 好的,对于您的测试,请尝试使用 127.0.0.1 而不是 localhost。对于客户端,请确保您的真实主机名具有 IPv4 或 IPv6 地址,而不是两者。 @Alexander Pogrebnyak 不是一直都在吗?

以上是关于为啥 request.getRemoteAddr() 根据上下文返回 ipv4 或 ipv6(post 查询或 ajax 查询)的主要内容,如果未能解决你的问题,请参考以下文章

急急急!谁能给我解释下String IPs=request.getRemoteAddr();啥意思啊

request.getRemoteAddr怎么获取用户真实的IP地址

request.getRemoteAddr()取得的是IPv6的地址格式解决方法

request.getRemoteAddr() 获取的值为0:0:0:0:0:0:0:1的原因及解决办法

根据Request获取客户端IP

根据Request获取客户端IP