我需要以某种方式使用JavaScript检索客户端的IP地址;没有服务器端代码,甚至没有SSI。
但是,我并不反对使用免费的第三方脚本/服务。
#1 楼
我将使用可以返回JSON的Web服务(与jQuery一起使事情变得更简单)。以下是我可以找到的所有免费的活动IP查找服务以及它们返回的信息。如果您知道更多,请添加评论,我将更新此答案。摘要
尝试一下:https://ipgeolocation.abstractapi.com/v1/?api_key =
$.getJSON('https://ipgeolocation.abstractapi.com/v1/?api_key=<your_api_key>', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip_address": "116.12.250.1",
"city": "Singapore (Queenstown Estate)",
"city_geoname_id": 1884386,
"region": null,
"region_iso_code": null,
"region_geoname_id": null,
"postal_code": null,
"country": "Singapore",
"country_code": "SG",
"country_geoname_id": 1880251,
"country_is_eu": false,
"continent": "Asia",
"continent_code": "AS",
"continent_geoname_id": 6255147,
"longitude": 103.807,
"latitude": 1.29199,
"timezone": {
"name": "Asia/Singapore",
"abbreviation": "+08",
"gmt_offset": 8,
"current_time": "22:33:13",
"is_dst": false
},
"flag": {
"emoji": "🇸🇬",
"unicode": "U+1F1F8 U+1F1EC",
"png": "https://static.abstractapi.com/country-flags/SG_flag.png",
"svg": "https://static.abstractapi.com/country-flags/SG_flag.svg"
},
"connection": {
"autonomous_system_number": 3758,
"autonomous_system_organization": "SingNet Pte Ltd",
"connection_type": "Corporate",
"isp_name": "SingNet Pte Ltd",
"organizaton_name": "Singapore Post LTD"
}
}
每月20,000个请求
需要注册才能获取您的API密钥
AstroIP.co
尝试一下:https://api.astroip.co/116.12.250.1/?api_key= <您的api_key>
$.getJSON('https://api.astroip.co/116.12.250.1/?api_key=<your_api_key>', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"status-code": 200,
"geo": {
"is-metric": true,
"is-in-europe": false,
"longitude": 103.7601,
"latitude": 1.3125,
"country-geo-id": 1880251,
"zip-code": "12",
"city": "Singapore",
"region-code": null,
"region-name": null,
"continent-code": "AS",
"continent-name": "Asia",
"capital": "Singapur",
"country-name": "Singapore",
"country-iso-code": "SG"
},
"asn": {
"route": "116.12.240.0/20",
"name": "SINGNET",
"type": "business",
"domain": "singtel.com",
"organization": "SingNet",
"asn": "AS3758"
},
"currency": {
"native-name": "新加坡元",
"code": "SGD",
"name": "Singapore Dollar",
"symbol": "$"
},
"timezone": {
"is-daylight-saving": false,
"gmt-offset": 28800,
"date-time": "2020-11-12T15:28:45+08:00",
"microsoft-name": "Asia/Singapore",
"iana-name": "Asia/Singapore"
},
"security": {
"is-crawler": false,
"is-proxy": false,
"is-tor": false,
"tor-insights": null,
"proxy-insights": null,
"crawler-insights": null
},
"crypto": null,
"user-agent": null,
"error": null,
"hostname": "116.12.250.1",
"ip-type": "ipv4",
"ip": "116.12.250.1"
}
局限性:
每月有30,000个免费请求
需要注册才能获取您的API密钥
Cloudflare
尝试一下:https://www.cloudflare.com/cdn-cgi/trace
// If your site is on Cloudflare, then you can use '/cdn-cgi/trace' instead
$.get('https://www.cloudflare.com/cdn-cgi/trace', function(data) {
console.log(data)
})
返回值:
fl=4f422
h=www.cloudflare.com
ip=54.193.27.106
ts=1575967108.245
visit_scheme=https
uag=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36 Hypothesis-Via
colo=SJC
http=http/1.1
loc=US
tls=TLSv1.3
sni=plaintext
warp=off
返回纯文本
DB-IP
尝试一下:http://api.db-ip.com/addrinfo?api_key=
返回值:
{
"address": "116.12.250.1",
"country": "SG",
"stateprov": "Central Singapore",
"city": "Singapore"
}
局限性:
每天2500个请求
不支持JSONP回调
要求es IP地址参数
需要电子邮件地址以获取您的API密钥
没有免费计划的SSL(https)
千兆字节
尝试一下: http://gd.geobytes.com/GetCityDetails
$.getJSON('http://gd.geobytes.com/GetCityDetails?callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
{
"geobytesforwarderfor": "",
"geobytesremoteip": "116.12.250.1",
"geobytesipaddress": "116.12.250.1",
"geobytescertainty": "99",
"geobytesinternet": "SA",
"geobytescountry": "Saudi Arabia",
"geobytesregionlocationcode": "SASH",
"geobytesregion": "Ash Sharqiyah",
"geobytescode": "SH",
"geobyteslocationcode": "SASHJUBA",
"geobytescity": "Jubail",
"geobytescityid": "13793",
"geobytesfqcn": "Jubail, SH, Saudi Arabia",
"geobyteslatitude": "27.004999",
"geobyteslongitude": "49.660999",
"geobytescapital": "Riyadh ",
"geobytestimezone": "+03:00",
"geobytesnationalitysingular": "Saudi Arabian ",
"geobytespopulation": "22757092",
"geobytesnationalityplural": "Saudis",
"geobytesmapreference": "Middle East ",
"geobytescurrency": "Saudi Riyal",
"geobytescurrencycode": "SAR",
"geobytestitle": "Saudi Arabia"
}
限制:
每小时16,384请求
否具有免费计划的SSL(https)
可以返回错误的位置(我在新加坡,而不是沙特阿拉伯)
GeoIPLookup.io
尝试一下: https://json.geoiplookup.io/api
$.getJSON('https://json.geoiplookup.io/api?callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
回报率:
{
"ip": "116.12.250.1",
"isp": "SGPOST",
"org": "Singapore Post Ltd",
"hostname": "116.12.250.1",
"longitude": "103.807",
"latitude": "1.29209",
"postal_code": "",
"city": "Singapore",
"country_code": "SG",
"country_name": "Singapore",
"continent_code": "AS",
"region": "Central Singapore",
"district": "",
"timezone_name": "Asia\/Singapore",
"connection_type": "",
"asn": "AS3758 SingNet",
"currency_code": "SGD",
"currency_name": "Singapore Dollar",
"success": true
}
限制:
每小时10,000个请求
免费API仅允许用于非商业用途
geoPlugin
尝试一下:http://www.geoplugin.net/json.gp
$.getJSON('http://www.geoplugin.net/json.gp?jsoncallback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回:
{
"geoplugin_request": "116.12.250.1",
"geoplugin_status": 200,
"geoplugin_credit": "Some of the returned data includes GeoLite data created by MaxMind, available from <a href=\'http://www.maxmind.com\'>http://www.maxmind.com</a>.",
"geoplugin_city": "Singapore",
"geoplugin_region": "Singapore (general)",
"geoplugin_areaCode": "0",
"geoplugin_dmaCode": "0",
"geoplugin_countryCode": "SG",
"geoplugin_countryName": "Singapore",
"geoplugin_continentCode": "AS",
"geoplugin_latitude": "1.2931",
"geoplugin_longitude": "103.855797",
"geoplugin_regionCode": "00",
"geoplugin_regionName": "Singapore (general)",
"geoplugin_currencyCode": "SGD",
"geoplugin_currencySymbol": "$",
"geoplugin_currencySymbol_UTF8": "$",
"geoplugin_currencyConverter": 1.4239
}
局限性:
每分钟120个请求
没有免费计划的SSL(https)
黑客目标
尝试一下:https://api.hackertarget.com/geoip/ ?q =
返回:
IP Address: 116.12.250.1
Country: SG
State: N/A
City: Singapore
Latitude: 1.293100
Longitude: 103.855797
限制:
50个请求每天
不支持JSONP回调
需要IP地址参数
返回纯文本
ipapi.co
尝试一下:https ://ipapi.co/json/
$.getJSON('https://ipapi.co/json/', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip": "116.12.250.1",
"city": "Singapore",
"region": "Central Singapore Community Development Council",
"country": "SG",
"country_name": "Singapore",
"postal": null,
"latitude": 1.2855,
"longitude": 103.8565,
"timezone": "Asia/Singapore"
}
每天有1,000个请求
需要SSL( https)
IP-API.com
尝试一下:http://ip-api.com/json
$.getJSON('http://ip-api.com/json?callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"as": "AS3758 SingNet",
"city": "Singapore",
"country": "Singapore",
"countryCode": "SG",
"isp": "SingNet Pte Ltd",
"lat": 1.2931,
"lon": 103.8558,
"org": "Singapore Telecommunications",
"query": "116.12.250.1",
"region": "01",
"regionName": "Central Singapore Community Development Council",
"status": "success",
"timezone": "Asia/Singapore",
"zip": ""
}
限制:
每分钟150个请求
免费计划无SSL(https)
Ipdata.co
:https://api.ipdata.co
$.getJSON('https://api.ipdata.co', function(data) {
console.log(JSON.stringify(data, null, 2));
});
收益:
{
"ip": "116.12.250.1",
"city": "Singapore",
"region": "Central Singapore Community Development Council",
"region_code": "01",
"country_name": "Singapore",
"country_code": "SG",
"continent_name": "Asia",
"continent_code": "AS",
"latitude": 1.2931,
"longitude": 103.8558,
"asn": "AS3758",
"organisation": "SingNet",
"postal": "",
"calling_code": "65",
"flag": "https://ipdata.co/flags/sg.png",
"emoji_flag": "\ud83c\uddf8\ud83c\uddec",
"emoji_unicode": "U+1F1F8 U+1F1EC",
"is_eu": false,
"languages": [
{
"name": "English",
"native": "English"
},
{
"name": "Malay",
"native": "Bahasa Melayu"
},
{
"name": "Tamil",
"native": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd"
},
{
"name": "Chinese",
"native": "\u4e2d\u6587"
}
],
"currency": {
"name": "Singapore Dollar",
"code": "SGD",
"symbol": "S$",
"native": "$",
"plural": "Singapore dollars"
},
"time_zone": {
"name": "Asia/Singapore",
"abbr": "+08",
"offset": "+0800",
"is_dst": false,
"current_time": "2018-05-09T12:28:49.183674+08:00"
},
"threat": {
"is_tor": false,
"is_proxy": false,
"is_anonymous": false,
"is_known_attacker": false,
"is_known_abuser": false,
"is_threat": false,
"is_bogon": false
}
}
限制:
每天1,500个请求
需要电子邮件地址才能获取您的API密钥
需要es SSL(https)
IP查找
尝试一下:https://ipfind.co/me?auth =
$.getJSON('https://ipfind.co/me?auth=<your_api_key>', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip_address": "116.12.250.1",
"country": "Singapore",
"country_code": "SG",
"continent": "Asia",
"continent_code": "AS",
"city": "Singapore",
"county": null,
"region": "Central Singapore",
"region_code": "01",
"timezone": "Asia/Singapore",
"owner": null,
"longitude": 103.8565,
"latitude": 1.2855,
"currency": "SGD",
"languages": [
"cmn",
"en-SG",
"ms-SG",
"ta-SG",
"zh-SG"
]
}
每天需要300个请求
需要注册才能获取您的API密钥
ipgeolocation
尝试一下:https://api.ipgeolocation.io/ipgeo?apiKey= <您的api_key>
$.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=<your_api_key>', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip": "116.12.250.1",
"continent_code": "AS",
"continent_name": "Asia",
"country_code2": "SG",
"country_code3": "SGP",
"country_name": "Singapore",
"country_capital": "Singapore",
"state_prov": "Central Singapore",
"district": "",
"city": "Singapore",
"zipcode": "",
"latitude": "1.29209",
"longitude": "103.807",
"is_eu": false,
"calling_code": "+65",
"country_tld": ".sg",
"languages": "cmn,en-SG,ms-SG,ta-SG,zh-SG",
"country_flag": "https://ipgeolocation.io/static/flags/sg_64.png",
"isp": "SGPOST",
"connection_type": "",
"organization": "Singapore Post Ltd",
"geoname_id": "1880252",
"currency": {
"name": "Dollar",
"code": "SGD"
},
"time_zone": {
"name": "Asia/Singapore",
"offset": 8,
"is_dst": false,
"current_time": "2018-06-12 09:06:49.028+0800"
}
}
局限性:
< br每月有50,000个请求
需要注册才能获得您的API密钥
ipify
尝试一下:https://api.ipify.org/?format = json
$.getJSON('https://api.ipify.org?format=jsonp&callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip": "116.12.250.1"
}
无
IPInfoDB
试试看:https://api.ipinfodb.com/v3/ip-city/?key=*
$.getJSON('https://api.ipinfodb.com/v3/ip-city/?key=<your_api_key>&format=json&callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"statusCode": "OK",
"statusMessage": "",
"ipAddress": "116.12.250.1",
"countryCode": "SG",
"countryName": "Singapore",
"regionName": "Singapore",
"cityName": "Singapore",
"zipCode": "048941",
"latitude": "1.28967",
"longitude": "103.85",
"timeZone": "+08:00"
}
局限性:
每秒两次请求
需要注册才能获取您的API密钥
ipinfo.io
尝试一下:https:/ /ipinfo.io/json
$.getJSON('https://ipinfo.io/json', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip": "116.12.250.1",
"hostname": "No Hostname",
"city": "Singapore",
"region": "Central Singapore Community Development Council",
"country": "SG",
"loc": "1.2931,103.8558",
"org": "AS3758 SingNet"
}
每天有1,000个请求
Ipregistry
尝试: https://api.ipregistry.co/?key=
$.getJSON('https://api.ipregistry.co/?key=<your_api_key>', function(data) {
console.log(JSON.stringify(data, null, 2));
});
回报:
{
"ip" : "116.12.250.1",
"type" : "IPv4",
"hostname" : null,
"carrier" : {
"name" : null,
"mcc" : null,
"mnc" : null
},
"connection" : {
"asn" : 3758,
"domain" : "singnet.com.sg",
"organization" : "SingNet Pte Ltd",
"type" : "isp"
},
"currency" : {
"code" : "SGD",
"name" : "Singapore Dollar",
"plural" : "Singapore dollars",
"symbol" : "SGD",
"symbol_native" : "SGD",
"format" : {
"negative" : {
"prefix" : "-SGD",
"suffix" : ""
},
"positive" : {
"prefix" : "SGD",
"suffix" : ""
}
}
},
"location" : {
"continent" : {
"code" : "AS",
"name" : "Asia"
},
"country" : {
"area" : 692.0,
"borders" : [ ],
"calling_code" : "65",
"capital" : "Singapore",
"code" : "SG",
"name" : "Singapore",
"population" : 5638676,
"population_density" : 8148.38,
"flag" : {
"emoji" : "🇸🇬",
"emoji_unicode" : "U+1F1F8 U+1F1EC",
"emojitwo" : "https://cdn.ipregistry.co/flags/emojitwo/sg.svg",
"noto" : "https://cdn.ipregistry.co/flags/noto/sg.png",
"twemoji" : "https://cdn.ipregistry.co/flags/twemoji/sg.svg",
"wikimedia" : "https://cdn.ipregistry.co/flags/wikimedia/sg.svg"
},
"languages" : [ {
"code" : "cmn",
"name" : "cmn",
"native" : "cmn"
}, {
"code" : "en",
"name" : "English",
"native" : "English"
}, {
"code" : "ms",
"name" : "Malay",
"native" : "Melayu"
}, {
"code" : "ta",
"name" : "Tamil",
"native" : "தமிழ்"
}, {
"code" : "zh",
"name" : "Chinese",
"native" : "中文"
} ],
"tld" : ".sg"
},
"region" : {
"code" : null,
"name" : "Singapore"
},
"city" : "Singapore",
"postal" : "96534",
"latitude" : 1.28967,
"longitude" : 103.85007,
"language" : {
"code" : "cmn",
"name" : "cmn",
"native" : "cmn"
},
"in_eu" : false
},
"security" : {
"is_bogon" : false,
"is_cloud_provider" : false,
"is_tor" : false,
"is_tor_exit" : false,
"is_proxy" : false,
"is_anonymous" : false,
"is_abuser" : false,
"is_attacker" : false,
"is_threat" : false
},
"time_zone" : {
"id" : "Asia/Singapore",
"abbreviation" : "SGT",
"current_time" : "2019-09-29T23:13:32+08:00",
"name" : "Singapore Standard Time",
"offset" : 28800,
"in_daylight_saving" : false
}
}
免费计划包括100,000个请求
需要注册才能获取您的API密钥
ipstack(以前为freegeoip.net)
尝试一下:http://api.ipstack。 com /
$.getJSON('http://api.ipstack.com/<ip_address>?access_key=<your_api_key>', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip": "116.12.250.1",
"type": "ipv4",
"continent_code": "AS",
"continent_name": "Asia",
"country_code": "SG",
"country_name": "Singapore",
"region_code": "01",
"region_name": "Central Singapore Community Development Council",
"city": "Singapore",
"zip": null,
"latitude": 1.2931,
"longitude": 103.8558,
"location": {
"geoname_id": 1880252,
"capital": "Singapore",
"languages": [{
"code": "en",
"name": "English",
"native": "English"
},
{
"code": "ms",
"name": "Malay",
"native": "Bahasa Melayu"
},
{
"code": "ta",
"name": "Tamil",
"native": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd"
},
{
"code": "zh",
"name": "Chinese",
"native": "\u4e2d\u6587"
}],
"country_flag": "http:\/\/assets.ipstack.com\/flags\/sg.svg",
"country_flag_emoji": "\ud83c\uddf8\ud83c\uddec",
"country_flag_emoji_unicode": "U+1F1F8 U+1F1EC",
"calling_code": "65",
"is_eu": false
}
}
每月10,000个请求
需要IP地址参数
需要注册才能获取您的API密钥
免费计划无SSL(https)
jsonip.com
尝试一下:https ://jsonip.com
$.getJSON('https://jsonip.com/?callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回:
{
"ip": "116.12.250.1",
"about": "https://jsonip.com/about",
"Pro!": "http://getjsonip.com",
"Get Notifications": "https://jsonip.com/notify"
}
响应包括加售
JSON测试
尝试一下:http://ip.jsontest.com/
$.getJSON('http://ip.jsontest.com/?callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"ip": "116.12.250.1"
}
没有SSL(https)
下降了很多(超出配额),因此我不会将其用于生产环境
如果有IP地址,则返回IPv6地址,这可能不是您想要的
/>
Nekudo
尝试一下:https://geoip.nekudo.com/api
$.getJSON('https://geoip.nekudo.com/api', function(data) {
console.log(JSON.stringify(data, null, 2));
});
返回值:
{
"city": "Singapore",
"country": {
"name": "Singapore",
"code": "SG"
},
"location": {
"accuracy_radius": 50,
"latitude": 1.2855,
"longitude": 103.8565,
"time_zone": "Asia/Singapore"
},
"ip": "116.12.250.1"
}
限制:
使用EasyPrivacy列表将广告拦截器封锁
请记住,由于这些都是免费服务,因此在超出配额和正常运行时间,谁知道何时/是否将它们离线(图表A:Telize)。如果您想要更多功能,例如SSL支持,这些服务中的大多数还提供付费层。
此外,正如skobaljic在下面的评论中指出的那样,请求配额大多是学术性的,因为这是在客户端和大多数最终用户中发生的永远不会超出配额。
更新
2/1/2016:删除了Telize(不再提供免费计划)
2016年4月18日:删除了freegeoip.net(停止服务)
2016年4月26日:添加了DB-IP
2016年4月26日:添加了黑客目标
2016年7月6日:恢复freegeoip.net
2016年7月6日:删除了ip-json.rhcloud.com(无效链接)
2016年12月21日:删除了Hacker Target(已停用)
2017年2月10日:添加了Nekudo
2017年4月20日:添加了ipapi.co(感谢Ahmad Awais)
4/24 / 2017:恢复了黑客目标
2017/4/24:删除了Snoopi.io(停止服务)
2017/7/16:添加了IP查找(感谢JordanC)
7/16/2017:更新了不支持SSL的免费计划的限制
9/25/2017:添加了愚蠢的Web工具(感谢Cœur)
3/16/2018:添加了Ipdata.co(谢谢乔纳森)
2018/4/14:将freegeoip.net重命名为ipstack(感谢MA-Maddin)
2018/4/16:添加了GeoIPLookup.io(感谢Rob Waa)
6 / 11/2018:添加了ipgeolocation(感谢Ejaz Ahmed)
2019/7/31:添加了Ipregistry(感谢Laurent)
2019/8/16:添加了SmartIP.io(感谢kevinj)
8 / 22/2019:移除了愚蠢的W eb工具(已停用)
12/8/2019:更改了智能IP月费限制
12/10/2019:添加了Cloudflare
1/9/2020:已删除SmartIP.io(服务中断)
11/6/2020:添加了摘要
11/13/2020:添加了AstroIP.co
#2 楼
最终更新此解决方案将不再起作用,因为浏览器正在修复webrtc泄漏:有关该问题的更多信息,请阅读另一个问题:RTCIceCandidate不再返回IP
更新:我一直想做一个最小/丑陋的代码版本,所以这是ES6 Promise代码:
var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
/*Usage example*/
findIP.then(ip => document.write('your ip: ', ip)).catch(e => console.error(e))
注意:如果您希望用户的所有IP(可能更多取决于用户的网络),请使用原始代码,此新的压缩代码将仅返回单个IP ...
由于使用了WebRTC,在支持WebRTC的浏览器中(至少现在)很容易获得本地IP。我已经修改了源代码,减少了行数,没有发出任何眩晕请求,因为您只需要本地IP,而不是公共IP,以下代码在最新的Firefox和Chrome中有效,只需运行代码段并检查一下即可:
function findIP(onNewIP) { // onNewIp - your listener function for new IPs
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
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 ipIterate(ip) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
pc.createDataChannel(""); //create a bogus data channel
pc.createOffer(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
}, noop); // create offer and set local description
pc.onicecandidate = function(ice) { //listen for candidate events
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
};
}
var ul = document.createElement('ul');
ul.textContent = 'Your IPs are: '
document.body.appendChild(ul);
function addIP(ip) {
console.log('got ip: ', ip);
var li = document.createElement('li');
li.textContent = ip;
ul.appendChild(li);
}
findIP(addIP);
<h1> Demo retrieving Client IP using WebRTC </h1>
这里正在发生的事情是,我们正在创建一个虚拟对等连接,对于远程对等与我们联系,我们通常会相互交换Ice候选对象。并从本地会话描述和onIceCandidateEvent中读取了ice候选对象,我们可以告诉用户的IP。
我从->源代码中获取代码的地方
评论
在这里投票,因为在这里给出了最佳答案,也感谢GitHub的出色仓库!
–卡诺
16年5月16日在10:49
警告:这不会显示您的公共IP,仅显示本地网络IP。您不能使用它来检测用户所在的国家(例如,如果他们位于局域网中)
–FloatingRock
16-11-23在8:20
@FloatingRock您也可以使用STUN服务器检索公共IP(并在创建对等设备时对其进行配置),然后再次要求您维护/使用STUN服务器,将服务器代码带入图片。
–mido
16年11月23日11:00
这称为WebRTC泄漏。应该由所有市长浏览器修复,但不是。此处的更多信息:privacytools.io/webrtc.html可能与Tor浏览器泄漏您的real-ip有关。
– Kapitein Witbaard
16年11月30日在10:25
虽然,我喜欢这个答案,但是客户端可以通过禁用WebRTC -restoreprivacy.com/webrtc-leaks来通过此过程
–ni8mr
19-10-28在10:55
#3 楼
您可以通过JSONP在服务器端进行中继,然后在谷歌搜索中找到一个,在此处找到它,这样我可以使用客户端Javascript执行DNS查找(从主机名到IP地址)吗? />
<script type="application/javascript">
function getip(json){
alert(json.ip); // alerts the ip address
}
</script>
<script type="application/javascript" src="http://www.telize.com/jsonip?callback=getip"></script>
注意:telize.com API已于2015年11月15日永久关闭。
评论
尽管我很欣赏此片段,但我认为加载JavaScript文本内容并通过函数进行评估会带来严重的安全风险。如果响应的内容发生变化,并且所有在此投票并可能使用了该摘要的100多个人最终都调用了可能包含不安全内容的功能,该怎么办。仅当它是JSON字符串时,我才使用它。
–auco
2013年11月25日15:26
配额错误此应用程序暂时超过了其服务配额。请稍后再试。
– Brad M
13年12月18日在15:06
这不是一个好答案,因为它涉及服务器端请求。该问题明确指出“纯javascript”。
–弥迦
2014年10月15日21:56
Micah,用纯JavaScript无法获得IP地址。我建议您对NAT及其工作原理进行一些阅读。您需要一台服务器将您的Internet IP地址回显给您
–乍得格兰特
14-10-17在0:54
现在服务已关闭。
–西里尔·N。
2015年8月14日10:00
#4 楼
这里的大多数答案都是通过...攻击他人的服务器来“解决”对服务器端代码的需求。除非您确实需要在不访问服务器的情况下获取IP地址,否则这是一种完全有效的技术。传统上,没有某种插件是不可能的(即使那样,如果您在NAT路由器后面,您可能会得到错误的IP地址),但是随着WebRTC的到来实际上可以这样做...如果您要针对支持WebRTC的浏览器(当前为Firefox,Chrome和Opera)。
有关如何使用WebRTC检索有用的客户端IP地址的详细信息,请阅读mido的答案。
评论
@oscar:这似乎与乍得在其回答中提到的技术(JSONP返回的服务器可见IP)相同。这与OP的“无服务器端代码”要求不符。但是,是的,如果您忽略了这一要求,那是实现它的一种方法。
– Shog9
2011-3-24在4:40
由于WebRTC,此答案已过时:stackoverflow.com/questions/20194722/…
– Akam
16年2月11日在10:32
更新,@ Akam。您应该给Mido提供一些支持,以便在几个月前指出这一点(多年以来,人们发布了令人尴尬的错误答案,但仍然需要服务器支持)。
– Shog9
16年2月11日在19:24
WebRTC现在得到更广泛的支持吗?
–老男孩
19年7月25日在20:22
根据该“ CanIUse”链接,它是@BugWhisperer。除非您需要IE。
– Shog9
19年7月25日在20:25
#5 楼
您可以对hostip.info或类似服务进行ajax调用...function myIP() {
if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest();
else xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET","http://api.hostip.info/get_html.php",false);
xmlhttp.send();
hostipInfo = xmlhttp.responseText.split("\n");
for (i=0; hostipInfo.length >= i; i++) {
ipAddress = hostipInfo[i].split(":");
if ( ipAddress[0] == "IP" ) return ipAddress[1];
}
return false;
}
另外,在同一调用中返回地理定位信息。
评论
您还可以使用api.hostip.info/get_json.php获取JSON表示形式,然后使用浏览器功能jQuery或Prototype解析JSON。
–布拉德·福尔肯斯(Brad Folkens)
2012-4-26 17:44
“ api.hostip.info/get_html.php”是否有任何请求限制?我在哪里可以看到此api详细信息
– Navin Leon
2012年6月20日7:29
它返回网络防火墙的IP。不是实际的客户端IP。有没有办法可以获取实际的客户端IP?
– Leela Addagulla
15年4月30日在19:39
#6 楼
试试这个$.get("http://ipinfo.io", function(response) {
alert(response.ip);
}, "jsonp");
OR
$(document).ready(function () {
$.getJSON("http://jsonip.com/?callback=?", function (data) {
console.log(data);
alert(data.ip);
});
});
提琴
评论
这适用于$ .get(“ ipinfo.io”,function(response){alert(response.ip);},“ jsonp”);但是如何将值存储到变量中?它似乎在此get请求循环之外消失了
–user1920216
2014-09-24 17:31
有关所有免费IP查找服务的列表,请参阅我的stackoverflow.com/questions/391979/…的答案。
– thdoan
16年2月1日,下午4:55
如何发送此函数以返回ip的值?
– Neftali Acosta
18年1月20日在22:43
#7 楼
别无所求查看http://www.ipify.org/
根据他们的内容:
您可以无限制地使用它(即使您每分钟处理数百万个请求)。
ipify是完全开源的(请查看GitHub存储库)。
这是一个工作的JS示例(而不是想知道为什么这个答案投票这么少,请自己尝试一下以付诸实践):
<script>
function getIP(json) {
alert("My public IP address is: " + json.ip);
}
</script>
<script src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
太懒了复制/粘贴?我喜欢。这是💻演示
懒得点击吗?
:O
注意:在运行演示之前请关闭Adblock Plus / uBlock&co ..否则,它将无法正常工作。
我与IPify团队无关。我只是觉得有人为一般利益提供这样的服务真是太荒谬了。
评论
最好的部分是,这来自“ https”,而我对http IP助手的调用会被阻止,因为它们“不安全”。
–泰莎
17 Mar 13 '13 at 13:41
嘿,它向我显示了CORS错误,该怎么办?
–佩剑药
19年11月1日在10:58
@saberprashant您在使用“ HTTPS”吗?
–FloatingRock
19年11月3日在16:26
@FloatingRock,不,我正在使用HTTP
–佩剑药
19年11月4日在9:19
有什么收获吗?
–佩帕
9月21日23:54
#8 楼
你不能您必须询问服务器。评论
这不能为问题提供答案。要批评或要求作者澄清,请在其帖子下方发表评论。
–Himanshu
2015年4月9日在4:09
但这有点吧?我的意思是,如果答案只是“不,您不能”,那么我认为这是一个比当前建议的“在这里使用此随机appspot应用程序”更正确的答案,这似乎是一个危险的答案。列表的顶部。
– SteveShaffer
2015年4月13日15:14
海事组织这是正确的答案,应该接受。该问题专门说“没有服务器端代码”。
–matthewwithanm
15年5月14日在15:28
stackoverflow.com/questions/20194722/…
– Akam
16年2月11日在10:33
@matthewwithanm我完全同意。我正在浏览所有答案,以查看是否有人说过这句话-并准备自己提供答案。所有高度支持的答案,虽然内容丰富,但都回答了一个不同的问题。提出问题:“我需要以某种方式使用纯JavaScript提取客户端的IP地址;没有服务器端代码,甚至没有SSI。”实际上,这个答案是正确的答案。使用浏览器沙盒的Javascript无法执行此操作(无论NAT或代理如何)。如果要接受其他答案之一,则应更改该问题。
– wally
17年8月7日在11:01
#9 楼
您可以为此使用我的服务http://ipinfo.io,它将为您提供客户端IP,主机名,地理位置信息和网络所有者。这是一个记录IP的简单示例:$.get("http://ipinfo.io", function(response) {
console.log(response.ip);
}, "jsonp");
这是一个更详细的JSFiddle示例,该示例还打印了完整的响应信息,因此您可以看到所有可用的详细信息:http://jsfiddle.net/zK5FN/2/
评论
为避免混合内容策略问题,请将http://ipinfo.io更改为//ipinfo.io或https
– Samuel Elh
18年4月29日在16:53
我们想使用您的服务,您是否对Stackoverflow用户有任何折扣优惠?
– Mehdi Dehghani
19/12/23在7:40
@MehdiDehghani,我们每月最多可免费提供5万个请求,并带有反向链接的10万个请求-请参阅ipinfo.io/contact/creditlink
–本·道林
19/12/23在15:06
#10 楼
在您的页面中包含以下代码:<script type="text/javascript" src="http://l2.io/ip.js"></script>
更多文档在这里
评论
嗯看起来很有趣...他们有什么限制?
– indapublic
2014年9月17日下午6:34
离线图书馆
–riccardo.tasso
18年8月23日在7:29
与l2.io相关的垃圾邮件弹出窗口在某种程度上与ref:hybrid-analysis.com/sample/…允许嵌入链接,如示例117.254.84.212:3000/getjs?nadipdata="{"url":"/ ip.js?var = myip“,”主机“:” l2.io“,”引荐来源“:” website.com /...}"& screenheight = 768&screenwidth = 1366&tm = 1557565256073&lib = true&fingerprint = c2VwLW5vLXJJlZGlyZWN0
– Wayne DSouza
19年5月11日在10:15
#11 楼
我想说乍得和马耳他有很好的答案。但是,它们很复杂。因此,我建议使用从国家/地区插件的广告中找到的这段代码。<script>
<script language="javascript" src="http://j.maxmind.com/app/geoip.js"></script>
<script language="javascript">
mmjsCountryCode = geoip_country_code();
mmjsCountryName = geoip_country_name();
</script>
没有ajax。只是普通的javascript。 :D
如果访问http://j.maxmind.com/app/geoip.js,您将看到它包含
function geoip_country_code() { return 'ID'; }
function geoip_country_name() { return 'Indonesia'; }
function geoip_city() { return 'Jakarta'; }
function geoip_region() { return '04'; }
function geoip_region_name() { return 'Jakarta Raya'; }
function geoip_latitude() { return '-6.1744'; }
function geoip_longitude() { return '106.8294'; }
function geoip_postal_code() { return ''; }
function geoip_area_code() { return ''; }
function geoip_metro_code() { return ''; }
它并没有真正回答问题,因为
http://j.maxmind.com/app/geoip.js不包含IP(尽管我打赌它使用IP来
但是制作PhP脚本以弹出类似
function visitorsIP() { return '123.123.123.123'; }
这样简单。放上http://yourdomain.com/yourip.php。然后做
<script language="javascript" src="http://yourdomain.com/yourip.php"></script>
这个问题专门提到了不要使用第三方脚本。没有别的办法了。 Javascript无法识别您的IP。但是其他可以通过javascript访问的服务器也可以正常工作。
评论
从远程服务器加载JavaScript并调用内容未知的函数对我来说似乎是一个巨大的安全隐患(如果函数内容更改,该怎么办?)。我宁愿解析JSON响应。
–auco
2013年11月25日15:35
错误404:找不到对象
– Trejder
2015年6月17日下午6:58
已经好长时间了,答案实际上是错误的。我不知道javascript不知道IP。
–user4951
17年1月19日在10:02
哦,没错,VisitorsIP函数并非旨在成为php代码。这是由php代码生成的javacript代码
–user4951
17年1月19日在10:03
您可以只使用自己的服务器,然后打印分配访问者IP的JavaScript代码。
–user4951
17年1月19日在10:04
#12 楼
这个问题有两种解释。大多数人将“客户端IP”解释为Web服务器在LAN外部和Internet上看到的公共IP地址。在大多数情况下,这不是客户端计算机的IP地址,我需要运行托管我的JavaScript软件的浏览器的计算机的真实IP地址(几乎总是本地在NAT层后面的LAN上的IP地址)。
Mido在上面发布了一个奇妙的答案,这似乎是唯一真正提供了客户端IP地址的答案。
,谢谢Mido!
但是,提供的功能异步运行。我需要在代码中实际使用IP地址,并且使用异步解决方案,我可能会尝试在检索/学习/存储IP地址之前使用它。在使用结果之前,我必须要等待结果。
这里是Mido函数的“ Waitable”版本。希望对其他人有所帮助:
function findIP(onNewIP) { // onNewIp - your listener function for new IPs
var promise = new Promise(function (resolve, reject) {
try {
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
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 ipIterate(ip) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
pc.createDataChannel(""); //create a bogus data channel
pc.createOffer(function (sdp) {
sdp.sdp.split('\n').forEach(function (line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
}, noop); // create offer and set local description
pc.onicecandidate = function (ice) { //listen for candidate events
if (ice && ice.candidate && ice.candidate.candidate && ice.candidate.candidate.match(ipRegex)) {
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
}
resolve("FindIPsDone");
return;
};
}
catch (ex) {
reject(Error(ex));
}
});// New Promise(...{ ... });
return promise;
};
//This is the callback that gets run for each IP address found
function foundNewIP(ip) {
if (typeof window.ipAddress === 'undefined')
{
window.ipAddress = ip;
}
else
{
window.ipAddress += " - " + ip;
}
}
//This is How to use the Waitable findIP function, and react to the
//results arriving
var ipWaitObject = findIP(foundNewIP); // Puts found IP(s) in window.ipAddress
ipWaitObject.then(
function (result) {
alert ("IP(s) Found. Result: '" + result + "'. You can use them now: " + window.ipAddress)
},
function (err) {
alert ("IP(s) NOT Found. FAILED! " + err)
}
);
<h1>Demo "Waitable" Client IP Retrieval using WebRTC </h1>
#13 楼
有一种更简单和免费的方法,它不会要求您的访客获得任何许可。它包括向http://freegeoip.net/json提交一个非常简单的Ajax POST请求。接收到位置信息后,使用JSON,您将通过更新页面或重定向到新页面来做出相应的反应。
这是您提交位置信息请求的方式:
jQuery.ajax( {
url: '//freegeoip.net/json/',
type: 'POST',
dataType: 'jsonp',
success: function(location) {
console.log(location)
}
} );
评论
看来他们已于2018年7月1日停产
– N.in P.H
18-09-28在12:24
#14 楼
好吧,我偏离了这个问题,但是今天我有类似的需求,尽管我无法使用Javascript从客户端找到ID,但是我做了以下操作。在服务器端:-
<div style="display:none;visibility:hidden" id="uip"><%= Request.UserHostAddress %></div>
使用Javascript
var ip = $get("uip").innerHTML;
我正在使用ASP.Net Ajax,但是可以使用getElementById代替发生的是,我在页面上有一个隐藏的div元素,其中用户IP是从服务器呈现的。比起用Java语言,我只是加载了该值。
这对像您这样有类似要求的人可能会有所帮助(像我一样,但我还没有弄清楚)。
欢呼!
评论
-1:OP专门提到“没有服务器端代码”,但是您使用了一些C#。
–布鲁诺·里斯(Bruno Reis)
2011年5月7日在8:36
只输出
评论
@AfolabiOlaoluwaAkinwumi,您可以尝试执行以下操作:$ .getJSON('// freegeoip.net/json/?callback=?',function(data){if(!data ||!data.ip)alert('找不到IP ');})。fail(function(){alert('$。getJSON()请求失败');});
– thdoan
16年11月24日在9:52
@skobaljic Re。限制通常没有任何意义:好处,也许是远离需要api密钥的原因,因为可以计算密钥的使用量。
–尼克·赖斯
17年5月4日在9:36
@JohnWeisz是的,但是如果OP仅意味着他们只能更新页面而不能在服务器端做任何事情(不清楚),那么这些选项可以很好地回答问题。
–尼克·赖斯
17年5月4日,9:43
@RobWaa,谢谢,我在4/14更新中添加了广告拦截器限制。我将很快添加geoiplookup.io。
– thdoan
18年4月17日在0:49
所有这些答案都依赖于第三方服务,这是一个很大的缺点,这不仅是因为您依赖该服务及时响应,而且还因为它不响应并且您没有设置适当的超时时间(这总是会发生的时间要晚一些),这将延迟页面的加载时间,这根本不好。那么,为什么不仅仅使用您自己的服务器来返回客户端的IP呢?顺便说一句,对于任何编程语言而言,这都是一项微不足道的任务。
–丹尼尔·J。
18/12/3在16:37