通过os
模块获取本地主机地址
需求来源
为什么要这么做呢?因为有个需求是用户可以在局域网内通过微信扫码跳转到点餐H5网页进行点餐,考虑到该H5网页可能运行在不同的局域网主机中,因此必须知道获取后端服务运行在哪个主机当中,比如我在本地的电脑通过pm2
起了一个node
服务,那么通过微信扫码访问的H5网页如果想要能够访问该node
服务的接口的话,就不能使用localhost来访问,只能使用主机的ip
地址来访问。那么,如何获取主机ip
地址呢?
获取本地主机地址的思路以及实现
思路
由于浏览器的限制,在前端获取主机ip
并不是一件容易的事情,因此刚开始我的想法就是在后端获取完主机ip
地址然后通过接口的方式返回给前端,然后前端将其保存为全局变量。但是由于后端服务有可能运行在局域网的不同主机上,因此他的局限是我前端需要你服务端主机的ip
地址来访问接口获取你的主机地址(这方案的可靠之处是我必须知道后端的主机ip
),但在这场景之下我并不能知道。这本身就是一件矛盾的事情。因此只能前端来做。但是前端应该怎么做呢?通过vite.config.ts
这个配置文件我知道了在前端项目中也能够引入node
相对应的模块,比如path
,os
等,恰巧os
模块能够正确的获取主机的ip
,到这问题就解决了。获取到主机ip
地址之后,我选择将其保存在vite
自带的全局变量import.meta.env
当中,这样子就能方便的存取了。
实现
javascript
import os from 'node:os'
const getLocalIp = () => {
const interfaces = os.networkInterfaces()
const addresses: string[] = []
for (const iface in interfaces) {
if (interfaces[iface]) {
for (const ifaceDetails of interfaces[iface]) {
if (ifaceDetails.family === 'IPv4' && !ifaceDetails.internal) {
addresses.push(ifaceDetails.address)
}
}
}
}
return addresses.length > 0 ? addresses[0] : 'localhost'
}
怎么将获取的主机
ip
地址保存到vite
全局变量呢?vite
官方提供了define
这个配置选项,我们只需要给这个配置选项新加一个键值对就可以了,键的格式必须为import.meta.env.xxx
,值必须为string
类型。类似如下:
javascript
export default defineConfig(() => ({
define: {
'import.meta.env.BASE_IP': JSON.stringify(address)
}
}))