l00*_*com 88 javascript ip-address
我知道对这个问题的最初反应是"不"和"它不可能完成"和"你不应该需要它,你做错了什么".我要做的是获取用户的LAN IP地址,并将其显示在网页上.为什么?因为这就是我正在处理的页面,尽可能多地显示关于您的信息,访问者:http: //www.whatsmyip.org/more-info-about-you/
所以我实际上并没有使用IP做任何事情,除了出于提供信息目的向用户显示.我曾经通过使用一个小的Java小程序来做到这一点.它工作得很好.但是现在,浏览器会让你多次同意和信任,甚至可以运行最小的java applet,我根本不会运行它.
所以有一段时间我只是摆脱了这个功能,但如果可能的话我会喜欢它.作为一名计算机顾问,我不时会实际使用它.访问此网站以查看网络运行的IP范围比进入系统偏好设置,网络连接以及任何活动界面更快.
所以我想知道,希望是否有一些方法可以单独在javascript中完成它?也许你可以访问一些新对象,类似于javascript可以询问浏览器在地球上的地理位置的方式.也许客户网络信息有类似之处?如果没有,也许还有其他一些方法可以完成吗?我能想到的唯一方法是java applet或flash对象.我宁愿不做其中任何一个.
afo*_*ney 109
事实证明,HTML5最近的WebRTC扩展允许javascript查询本地客户端IP地址.这里有一个概念证明:http://net.ipcalf.com
这个功能显然是设计使然,并不是一个bug.但是,鉴于其有争议的性质,我会谨慎依赖这种行为.尽管如此,我认为它完全适当地解决了您的预期目的(向用户透露他们的浏览器漏洞).
mid*_*ido 75
除了afourney的答案,此代码适用于支持WebRTC(Chrome和Firefox)的浏览器.我听说有一个动作正在实现一个功能,使网站请求IP(如用户的地理位置或用户媒体),虽然它尚未在任何一个浏览器中实现.
这是源代码的修改版本,减少了行数,没有发出任何眩晕请求,因为您只需要本地IP而不是公共IP:
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;//compatibility for Firefox and chrome
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
pc.createDataChannel('');//create a bogus data channel
pc.createOffer(pc.setLocalDescription.bind(pc), noop);// create offer and set local description
pc.onicecandidate = function(ice)
{
if (ice && ice.candidate && ice.candidate.candidate)
{
var myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
console.log('my IP: ', myIP);
pc.onicecandidate = noop;
}
};
Run Code Online (Sandbox Code Playgroud)
我们正在为远程对等方创建一个虚拟对等连接来联系我们.我们通常互相交换冰候选人并阅读我们可以告诉用户ip的冰候选人.
我清理了mido的帖子,然后清理了他们找到的功能.这将返回false或array.测试时记得你需要在Web开发者控制台中折叠数组,否则它是非直观的默认行为可能会欺骗你以为它返回一个空的array.
function ip_local()
{
var ip = false;
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || false;
if (window.RTCPeerConnection)
{
ip = [];
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
pc.createDataChannel('');
pc.createOffer(pc.setLocalDescription.bind(pc), noop);
pc.onicecandidate = function(event)
{
if (event && event.candidate && event.candidate.candidate)
{
var s = event.candidate.candidate.split('\n');
ip.push(s[0].split(' ')[4]);
}
}
}
return ip;
}
Run Code Online (Sandbox Code Playgroud)
另外请记住,这不是像CSS那样的新旧东西,border-radius尽管其中一个是IE11及以前不支持的.始终使用对象检测,在合理的旧浏览器(例如Firefox 4,IE9,Opera 12.1)中进行测试,并确保您的新脚本不会破坏您的新代码.另外总是检测标准的代码第一,所以如果有什么用说CSS前缀检测标准的非前缀码第一,然后回落作为长期的支持最终将被标准化为它的存在的其余部分.
小智 8
该的WebRTC API可用于检索客户端的本地IP。
但是,浏览器可能不支持它,或者客户端可能出于安全原因已将其禁用。无论如何,从长远来看,不应依赖此“ hack”,因为将来可能会对其进行修补(请参阅Cullen Fluffy Jennings的回答)。
下面的ECMAScript 6代码演示了如何执行此操作。
/* ES6 */
const findLocalIp = (logInfo = true) => new Promise( (resolve, reject) => {
window.RTCPeerConnection = window.RTCPeerConnection
|| window.mozRTCPeerConnection
|| window.webkitRTCPeerConnection;
if ( typeof window.RTCPeerConnection == 'undefined' )
return reject('WebRTC not supported by browser');
let pc = new RTCPeerConnection();
let ips = [];
pc.createDataChannel("");
pc.createOffer()
.then(offer => pc.setLocalDescription(offer))
.catch(err => reject(err));
pc.onicecandidate = event => {
if ( !event || !event.candidate ) {
// All ICE candidates have been sent.
if ( ips.length == 0 )
return reject('WebRTC disabled or restricted by browser');
return resolve(ips);
}
let parts = event.candidate.candidate.split(' ');
let [base,componentId,protocol,priority,ip,port,,type,...attr] = parts;
let component = ['rtp', 'rtpc'];
if ( ! ips.some(e => e == ip) )
ips.push(ip);
if ( ! logInfo )
return;
console.log(" candidate: " + base.split(':')[1]);
console.log(" component: " + component[componentId - 1]);
console.log(" protocol: " + protocol);
console.log(" priority: " + priority);
console.log(" ip: " + ip);
console.log(" port: " + port);
console.log(" type: " + type);
if ( attr.length ) {
console.log("attributes: ");
for(let i = 0; i < attr.length; i += 2)
console.log("> " + attr[i] + ": " + attr[i+1]);
}
console.log();
};
} );
Run Code Online (Sandbox Code Playgroud)
请注意,我写return resolve(..)或return reject(..)作为快捷方式。这两个函数均不返回任何内容。
然后,您可能会有以下内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Local IP</title>
</head>
<body>
<h1>My local IP is</h1>
<p id="ip">Loading..</p>
<script src="ip.js"></script>
<script>
let p = document.getElementById('ip');
findLocalIp().then(
ips => {
let s = '';
ips.forEach( ip => s += ip + '<br>' );
p.innerHTML = s;
},
err => p.innerHTML = err
);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
小智 6
function getUserIP(onNewIP) { // onNewIp - your listener function for new IPs
//compatibility for firefox and chrome
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new myPeerConnection({
iceServers: []
}),
noop = function() {},
localIPs = {},
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key;
function iterateIP(ip) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
onNewIP
//create a bogus data channel
pc.createDataChannel("");
// create offer and set local description
pc.createOffer().then(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(iterateIP);
});
pc.setLocalDescription(sdp, noop, noop);
}).catch(function(reason) {
// An error occurred, so handle the failure to connect
});
//listen for candidate events
pc.onicecandidate = function(ice) {
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(iterateIP);
};
}
getUserIP(console.log)Run Code Online (Sandbox Code Playgroud)
去年,我使用 Linblow 的回答(2018 年 10 月 19 日)通过 javascript 成功发现了我的本地 IP。但是,最近的 Chrome 更新(76?)已经使用了这种方法,因此它现在返回一个混淆的 IP,例如:1f4712db-ea17-4bcf-a596-105139dfd8bf.local
如果您可以完全控制浏览器,则可以通过在地址栏中键入以下内容在 Chrome Flags 中将其关闭来撤消此行为:
chrome://flags
Run Code Online (Sandbox Code Playgroud)
和禁用标志 Anonymize local IPs exposed by WebRTC
就我而言,我需要 TamperMonkey 脚本的 IP 来确定我的当前位置并根据我的位置执行不同的操作。我还可以完全控制自己的浏览器设置(无公司政策等)。所以对我来说,改变chrome://flags设置就能解决问题。
资料来源:
https://groups.google.com/forum/#!topic/discuss-webrtc/6stQXi72BEU
https://codelabs.developers.google.com/codelabs/webrtc-web/index.html
现在支持内部 IP!
RTCPeerConnection可以使用安。在像 Chrome 这样getUserMedia需要权限的浏览器中,我们只能检测可用的输入设备并请求它们。
const internalIp = async () => {
if (!RTCPeerConnection) {
throw new Error("Not supported.")
}
const peerConnection = new RTCPeerConnection({ iceServers: [] })
peerConnection.createDataChannel('')
peerConnection.createOffer(peerConnection.setLocalDescription.bind(peerConnection), () => { })
peerConnection.addEventListener("icecandidateerror", (event) => {
throw new Error(event.errorText)
})
return new Promise(async resolve => {
peerConnection.addEventListener("icecandidate", async ({candidate}) => {
peerConnection.close()
if (candidate && candidate.candidate) {
const result = candidate.candidate.split(" ")[4]
if (result.endsWith(".local")) {
const inputDevices = await navigator.mediaDevices.enumerateDevices()
const inputDeviceTypes = inputDevices.map(({ kind }) => kind)
const constraints = {}
if (inputDeviceTypes.includes("audioinput")) {
constraints.audio = true
} else if (inputDeviceTypes.includes("videoinput")) {
constraints.video = true
} else {
throw new Error("An audio or video input device is required!")
}
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints)
mediaStream.getTracks().forEach(track => track.stop())
resolve(internalIp())
}
resolve(result)
}
})
})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
139765 次 |
| 最近记录: |