目录
一、获取访问端IP地址
二、可用的IP获取接口
1、韩小韩IP获取接口:
2、ipify API
附3、失败的太平洋接口
三、腾讯位置服务-IP位置查询接口
一、获取访问端IP地址
原计划使用后端HttpServletRequest 获取访问端的IP地址,但在nginx和堡垒机等阻碍下始终只能获得网关的地址,方法如下:
public String buildLicense_2(@RequestBody Map map, HttpServletRequest request){
//只能获取到网关的ip,获取不到真实IP
String ipAddress = IpUtil.getIpAddr(request);
System.err.println("IP地址:"+ipAddress);
}
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
System.out.println("x-forwarded-for IP地址:"+ip);
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
System.out.println("Proxy-Client-IP IP地址:"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
System.out.println("X-Forwarded-For IP地址:"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
System.out.println("WL-Proxy-Client-IP IP地址:"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
System.out.println("X-Real-IP IP地址:"+ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
try{
System.out.println("getRemoteAddr() IP地址:"+request.getRemoteAddr());
}
catch (Exception ex){
}
return "0:0:0:0:0:0:0:1".equals(ip) ? LOCAL_IP : ip;
}
故在前端通过第三方接口,获取当前ip地址后再传到后端
具体如下:
function getIpInfo() {
$.ajax({
url: "https://api.vvhan.com/api/visitor.info",// "https://api.ipify.org?format=json",
type: "GET",
//data: { val1: "1", val2: "2" },
dataType: "json",
success: function (result) {
console.log("IP地址:");
console.log(result);
ipData = result;
},
error: function () {
console.log('获取ip失败');
}
});
}
二、可用的IP获取接口
如上所示,使用的是第三方
1、韩小韩IP获取接口:
API地址:https://api.vvhan.com/api/visitor.info
API文档地址:https://api.vvhan.com/fangke.html
返回示例:
使用说明:
韩小韩接口站API大全:韩小韩API接口站 - 免费API数据接口调用服务平台
2、ipify API
API地址:https://api.ipify.org?format=json
官网地址:https://www.ipify.org/
可再各个环境下调用
附3、失败的太平洋接口
var whois = {
root: 'http://whois.pconline.com.cn',
version: 2.0,
jsonIp: function () {
var s = document.getElementsByTagName('head')[0].appendChild(document.createElement("script"));
/*s.src = this.root + "/jsAlert.jsp?ip=" + ip;*/
s.type = "application/javascript";
s.src = this.root + "/ipJson.jsp?callback=callbackRepos";
console.log(s.src);
},
lableIp: function (id, ip) {
var s = document.getElementsByTagName('head')[0].appendChild(document.createElement("script"));
s.src = this.root + "/jsLabel.jsp?ip=" + ip + "&id=" + id;
}
}
function getCurIP() {
whois.jsonIp();
}
function callbackRepos(res) {
console.log(res);
//var data = JSON.stringify(res); //json对象转成字符串
//console.log(data);
ipData = res;
}
接口地址:
http://whois.pconline.com.cn
http://whois.pconline.com.cn/ipJson.jsp
只能以如上所示方式调用,在本地可用,一旦部署到外网环境下就是会失败403错误。还会存在跨域问题。所以此法不可用,却浪费了我许多时间。
三、腾讯位置服务-IP位置查询接口
在后台通过腾讯接口将IP地址转换为县区市级别的位置信息,以上的接口只能查询到地级市。
API文档地址:WebService API | 腾讯位置服务
注册腾讯位置服务,创建App,获取app key之后即可在后台调用,
如下所示,返回 省-市-县-县代码
String s = sendGet(ip, KEY);
// System.out.println("IP地址查询结果s=" + s);
JSONObject map =new JSONObject(s);
String message = (String) map.get("message");
if("Success".equals(message)){
Map result = (Map) map.get("result");
Map addressInfo = (Map) result.get("ad_info");
String nation = (String) addressInfo.get("nation");
String province = (String) addressInfo.get("province");
String district = (String) addressInfo.get("district");
String city = (String) addressInfo.get("city");
Integer XZQDM = (Integer) addressInfo.get("adcode");
String address = province + "-" + city + "-" + district + "-" + XZQDM;
return address;
}else{
System.out.println("message="+message);
return message;
}
//根据在腾讯位置服务上申请的key进行请求操作
private static String sendGet(String ip, String key) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = "https://apis.map.qq.com/ws/location/v1/ip?ip="+ip+"&key="+key;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
// for (Map.Entry entry : map.entrySet()) {
// System.out.println(key + "--->" + entry);
// }
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
附参考文章:
Ajax请求后端接口(GET、POST、轮询请求)_ajax post_IamaMartian的博客-CSDN博客