1.场景分析
最近有个需求,有个功能只能让外网用户使用,内网用户无感,并且是在同一个引用中,那么我就需要在初始化的时候,对当前用户的IP进行判断,看看这个IP是否可以访问内网
2.前端实现
前端实现就一个思路,用AJAX调用一个只有内网可以访问的到的数据或者接口。如果超时了,那么就是外网。
//代码主体
ping = (address,callback) =>{
var img = new Image();
var start = new Date().getTime();
//一张内网图片 用来判断网络类型 外网是加载不到这个图片的
img.src =address+"?time="+start;
var flag = false;
img.onload = function(){
flag = true;
//在2秒内 加载出图片 那么就认定为是内网
console.log("内网网络")
}
var timer = setTimeout(function(){
if(!flag){
flag = false;
if (callback && typeof callback == 'function') callback();
}
},2000);
}
//使用回调函数触发我们的事件
this.ping("http://neiwang.com/static/img/4345wee68dsfsd.png",()=>{
//只有外网才会执行这个回调
alert("我是外网")
})
代码很简单,只要在定时器到达之前响应我们信息,那就是内网,但是存在一个很严重的风险
假如用来校验内网的那个资源被删了或者接口挂了,那么我们的全部IP都会视为外网,因为你统统都超时了。或者假如我们网络震荡,或者加载的资源很大,也会造成问题。所以想用这个办法一定要保证,用来校验的资源或者接口一定要很快,资源保证不会被误删。最好专门写一个接口或者一个小图片来做接口超时的判断。不要随便哪一个好几十M的图片,万一网络炸了就完蛋了。
3.后端实现
public static boolean test() throws IOException {
String ip = "apaddress";
Runtime runtime = Runtime.getRuntime(); // 获取当前程序的运行进对象
Process process = null; //声明处理类对象
String line = null; //返回行信息
InputStream is = null; //输入流
InputStreamReader isr = null;// 字节流
BufferedReader br = null;
boolean res = false;// 结果
try {
process = runtime.exec("ping " + ip); // PING
is = process.getInputStream(); // 实例化输入流
isr = new InputStreamReader(is);// 把输入流转换成字节流
br = new BufferedReader(isr);// 从字节中读取文本
while ((line = br.readLine()) != null) {
//这里一定要转大写 因为在linux系统中,是小写的 要兼容系统就加上
if (line.toUpperCase().contains("TTL")) {
res = true;
break;
}
}
if (res) {
return true;
} else {
return false;
}
} catch (IOException e) {
runtime.exit(1);
return false;
} finally {
if (is != null) {
is.close();
}
if (isr != null) {
isr.close();
}
if (br != null) {
br.close();
}
}
}
我个人更加倾向于用后端去实现,这个只需要使用IP即可,无需其他资源,更加安全。
4.注意事项
如果使用后端方式的小伙伴注意,因为java模拟PING请求,如果通不了的话可能会造成长时间的卡顿,因为获取请求的方式是while循环,存在卡顿的情况。所以在调用这个接口的时候,ajax一定要加上超时时间。避免无线等待造成其他问题。
参考代码如下:
ipAddressPing = (ip,callback,timeout=2000)=>{
$.ajax({
url:'/api/demo/ipAddressPing?ipAddress='+ip,
type:'get',
timeout:timeout, //设置超时的时间2s
success:function(res){
console.log(res)
//请求没超时,但是PING不通,也说明是外网 需要调用接口 这里具体的你们自行判断
if (!res) {
if (callback && typeof callback == 'function') callback(res);
}
},
error:function(err){
console.log(err)
//请求超时说明 外网 需要调用接口
if (callback && typeof callback == 'function') callback(res);
}
})
}