判断当前请求的网络是内网还是外网

2022-07-26 11:55:55

1.场景分析

最近有个需求,有个功能只能让外网用户使用,内网用户无感,并且是在同一个引用中,那么我就需要在初始化的时候,对当前用户的IP进行判断,看看这个IP是否可以访问内网

2.前端实现

前端实现就一个思路,用AJAX调用一个只有内网可以访问的到的数据或者接口。如果超时了,那么就是外网。

//代码主体ping=(address,callback)=>{var img=newImage();var start=newDate().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.后端实现

publicstaticbooleantest()throwsIOException{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=newInputStreamReader(is);// 把输入流转换成字节流
            br=newBufferedReader(isr);// 从字节中读取文本while((line= br.readLine())!=null){//这里一定要转大写 因为在linux系统中,是小写的 要兼容系统就加上if(line.toUpperCase().contains("TTL")){
                    res=true;break;}}if(res){returntrue;}else{returnfalse;}}catch(IOException e){
            runtime.exit(1);returnfalse;}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,//设置超时的时间2ssuccess: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);}})}
  • 作者:锦哥哥(API调用工程师)
  • 原文链接:https://blog.csdn.net/BrotherJinJin/article/details/125783590
    更新时间:2022-07-26 11:55:55