目录
一、获取访问端IP地址
二、可用的IP获取接口
1、韩小韩IP获取接口:
2、ipify API
附3、失败的太平洋接口
三、腾讯位置服务-IP位置查询接口
一、获取访问端IP地址
原计划使用后端HttpServletRequest 获取访问端的IP地址,但在nginx和堡垒机等阻碍下始终只能获得网关的地址,方法如下:
public String buildLicense_2(@RequestBody Map map, HttpServletRequest request){//只能获取到网关的ip,获取不到真实IPString 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博客