ping 域名

突然遇到这么个需求,需要判断是否内网环境。
这个问题,如果想通了就非常简单。

尝试一 ajax

一开始,我想到的是 ajax 访问内网接口,不通就外网,通就内网。
这会有个小问题,需要服务器加上跨域支持。

而且用户浏览器可能也会有兼容性问题。
所以放弃。

尝试二 img 大法

这个是比较靠谱的方式,就是 img 加载内网图片,如果成功,那就是内网,没有兼容性问题。
思路就是 new Image 然后加载内网ip的图标,比如 ‘http://192.168.1.12/favicon.ico'。

1
2
3
4
const img = new Image();
img.onload = () => '是内网,执行相关代码';
img.onerror = () => '不是内网,执行相关代码';
img.src = 'http://192.168.1.12/favicon.ico?_=' + (+new Date());

但如果你的内网服务没 favicon.ico,那 logo 总会有吧,或者其他任意图片。

npm 模块

于是乎就写了个模块 ping-host

安装:

1
2
3
$ yarn add ping-host
# 或
$ npm i -S ping-host

使用:

1
2
3
4
5
6
7
8
import ping from 'ping-host';

(async () => {
await ping('taobao.com');
await ping('github.com', 'fluidicon.png');
await ping('github.com', 5000);
await ping('github.com', 'fluidicon.png', 3000);
})();

或页面直接引入:

1
2
3
4
5
6
7
8
9
<script src="https://unpkg.com/ping-host"></script>
<script>
(async () => {
const ret = await ping('taobao.com');
})();

// 或
ping('taobao.com').then(ret => console.log(ret));
</script>

ping(host, image, timeout)

host: string, 域名或IP

image: 图片,默认 favicon.ico

timeout: 超时(毫秒),默认不限制

小结

很多时候都只差灵光一现,一些很 low 的技巧,也可以用出高大上的效果。