如何通过JavaScript获取局域网PC中ipconfig显示的IPv4地址?
如何获取访问Web应用的局域网PC的IPv4地址
问题背景
办公室内PC通过局域网(LAN)连接,分配A类IP地址,Web应用部署在外部服务器,局域网内PC可正常访问。尝试用JavaScript和Java代码获取客户端ipconfig命令显示的IPv4地址时遇到问题:
- JavaScript代码本地测试时可正常返回IPv4,但部署到服务器后结果异常
- Java代码返回的是Web应用所在服务器的IPv4,而非访问客户端的IPv4
现有代码问题分析
JavaScript代码问题
原代码基于WebRTC获取本地IP,本地测试正常是因为浏览器直接访问本地资源,无跨域或网络环境变化;部署到服务器后异常的原因通常包括:
- 服务器启用HTTPS,浏览器对WebRTC暴露本地IP有更严格的隐私限制
- 网络环境存在NAT或代理,WebRTC获取到的是经过转换的地址而非局域网原生IP
- 浏览器隐私设置阻止WebRTC获取本地IP
原JavaScript代码:
<script> var RTCPeerConnection = /*window.RTCPeerConnection ||*/ window.webkitRTCPeerConnection || window.mozRTCPeerConnection; if (RTCPeerConnection)(function() { var rtc = new RTCPeerConnection({ iceServers: [] }); if (1 || window.mozRTCPeerConnection) { rtc.createDataChannel('', { reliable: false }); }; rtc.onicecandidate = function(evt) { if (evt.candidate) grepSDP("a=" + evt.candidate.candidate); }; rtc.createOffer(function(offerDesc) { grepSDP(offerDesc.sdp); rtc.setLocalDescription(offerDesc); }, function(e) { console.warn("offer failed", e); }); var addrs = Object.create(null); addrs["0.0.0.0"] = false; function updateDisplay(newAddr) { if (newAddr in addrs) return; else addrs[newAddr] = true; var displayAddrs = Object.keys(addrs).filter(function(k) { return addrs[k]; }); document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a"; } function grepSDP(sdp) { var hosts = []; sdp.split('\r\n').forEach(function(line) { if (~line.indexOf("a=candidate")) { var parts = line.split(' '), addr = parts[4], type = parts[7]; if (type === 'host') updateDisplay(addr); } else if (~line.indexOf("c=")) { var parts = line.split(' '), addr = parts[2]; updateDisplay(addr); } }); } })(); else { document.getElementById('list').innerHTML = "<code>ifconfig| grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>"; document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull."; } </script>
Java代码问题
原Java代码在服务器端执行,遍历的是服务器自身的网络接口,因此必然返回服务器IP,而非客户端IP。客户端IP需要从HTTP请求的头信息中获取。
原Java代码:
Enumeration<NetworkInterface> interfaces=NetworkInterface.getNetworkInterfaces(); while(interfaces.hasMoreElements()){ NetworkInterface current=interfaces.nextElement(); Enumeration<InetAddress> addresses=current.getInetAddresses(); while(addresses.hasMoreElements()){ InetAddress current_addr=addresses.nextElement(); if(current_addr instanceof Inet4Address){ String hostAddr=current_addr.getHostAddress(); String hostName=current_addr.getHostName(); } } }
解决方案
方案1:服务器端从HTTP请求获取客户端IP(推荐)
客户端访问Web应用时,HTTP请求头会携带客户端IP信息,服务器端可通过以下方式提取:
Java Servlet环境示例
public String getClientIpAddress(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } // 多代理场景下取第一个非unknown的IP if (ip != null && ip.contains(",")) { ip = ip.split(",")[0].trim(); } return ip; }
注意:若服务器部署在反向代理(如Nginx)之后,需配置代理将真实客户端IP传递到请求头中,否则获取到的是代理服务器的IP。
方案2:修复JavaScript代码(仅适用于HTTP环境或特定浏览器配置)
若必须通过前端获取,需调整代码并注意浏览器限制:
- 确保服务器使用HTTP(HTTPS下浏览器可能限制WebRTC暴露本地IP)
- 新增A类局域网IP过滤逻辑(匹配10.0.0.0/8网段)
调整后的JavaScript代码:
<script> var RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection; if (RTCPeerConnection) { (function() { var rtc = new RTCPeerConnection({ iceServers: [] }); rtc.createDataChannel('', { reliable: false }); rtc.onicecandidate = function(evt) { if (evt.candidate) grepSDP("a=" + evt.candidate.candidate); }; rtc.createOffer(function(offerDesc) { grepSDP(offerDesc.sdp); rtc.setLocalDescription(offerDesc); }, function(e) { console.warn("offer failed", e); }); var addrs = Object.create(null); addrs["0.0.0.0"] = false; function isLanA类(ip) { // 匹配A类局域网IP(10.0.0.0-10.255.255.255) return /^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(ip); } function updateDisplay(newAddr) { if (newAddr in addrs || !isLanA类(newAddr)) return; addrs[newAddr] = true; var displayAddrs = Object.keys(addrs).filter(function(k) { return addrs[k]; }); document.getElementById('list').textContent = displayAddrs.join(" ") || "n/a"; } function grepSDP(sdp) { sdp.split('\r\n').forEach(function(line) { if (~line.indexOf("a=candidate")) { var parts = line.split(' '), addr = parts[4], type = parts[7]; if (type === 'host') updateDisplay(addr); } }); } })(); } else { document.getElementById('list').innerHTML = "<code>ipconfig | findstr /i \"IPv4\"</code>"; document.getElementById('list').nextSibling.textContent = "在Chrome和Firefox中,WebRTC可自动显示你的IP。"; } </script>
注意:HTTPS环境下,部分浏览器(如Chrome)会隐藏本地局域网IP,仅暴露公网IP,此方案可能失效。
总结
- 优先使用服务器端从HTTP请求获取客户端IP,这是最可靠的方式
- 前端WebRTC方式受浏览器环境和网络配置限制,仅适用于特定场景
内容的提问来源于stack exchange,提问作者Sanghamitra Lahiri
相关产品推荐
相关产品推荐

