社交媒体

在vue项目合并部署模式下如何获取ip地址,实现局域网部署

步骤一:引入必要的库

Node.js 是一个单线程的 JavaScript 运行时环境,但有时候我们需要执行一些系统命令或运行其他程序。这时就需要用到 child_process 模块。

child_process 模块允许 Node.js 应用程序创建子进程,这些子进程可以执行系统命令、运行其他脚本或程序,并与父进程进行通信。

这样做的好处

  1. 执行系统命令:比如执行 lsgit 等命令行工具

  2. 运行 CPU 密集型任务:避免阻塞 Node.js 主线程

  3. 与其他语言编写的程序交互:比如调用 Python 或 C++ 程序

  4. 提高应用性能:通过多进程充分利用多核 CPU

实际应用如下:

import os from 'os'
import { execSync } from 'child_process'

步骤二:构造相关函数


function getNetworkInfo() {
  let ssid = '未知'
  let ipv4 = '127.0.0.1'

  try {
    const interfaces = os.networkInterfaces()
    for (const interfaceName of Object.keys(interfaces)) {
      for (const iface of interfaces[interfaceName]) {
        if (iface.family === 'IPv4' && !iface.internal) {
          ipv4 = iface.address
          break
        }
      }
      if (ipv4 !== '127.0.0.1') break
    }
  } catch (error) {
    console.error('[网络信息] 获取IPv4地址失败:', error)
  }

  try {
    const output = execSync('netsh wlan show interfaces', { encoding: 'utf-8' })
    const ssidMatch = output.match(/SSID\s+:\s(.+)/)
    if (ssidMatch && ssidMatch[1]) {
      ssid = ssidMatch[1].trim()
    }
  } catch (error) {
    console.error('[网络信息] 获取WiFi名称失败:', error)
  }

  return { ssid, ipv4 }
}

说明:

$变量

值key

含义

ssid

未知(默认)

WIFI名称

ipv4

127.0.0.1(默认)

IPv4地址

os.networkInterfaces() 是 Node.js 内置方法,返回对象,键 = 网卡名称(Windows:以太网WLAN;Mac/Linux:en0eth0wlan0),值 = 当前网卡的所有网络地址数组,包含 IPv4、IPv6、MAC、是否内网等信息

返回数据示例:

{
  WLAN: [
    { address: '192.168.1.100', family: 'IPv4', internal: false },
    { address: 'fe80::xxxx', family: 'IPv6', internal: false }
  ],
  lo: [{ address: '127.0.0.1', family: 'IPv4', internal: true }] // 本地回环网卡
}

第一层循环:遍历所有网卡名称

for (const interfaceName of Object.keys(interfaces))

取出所有网卡名(WLANlo以太网等)逐个遍历

第二层循环:遍历单网卡下的所有地址

for (const iface of interfaces[interfaceName])

一个网卡会同时拥有 IPv4、IPv6 多个地址,循环逐个判断

筛选条件(关键判断)

if (iface.family === 'IPv4' && !iface.internal) {
  ipv4 = iface.address
  break
}

两个筛选规则:

  1. family === 'IPv4':只拿 IPv4 地址,跳过 IPv6;

  2. !iface.internalinternal=true 代表本机内部回环地址(就是 127.0.0.1),直接排除,只取物理网卡真实局域网地址

匹配成功,把地址赋值给变量 ipv4,跳出当前网卡的地址循环

拿到合法 IP 就终止外层循环

if (ipv4 !== '127.0.0.1') break

只要拿到的 IP 不是本地回环地址,直接跳出网卡外层循环,不再遍历剩余网卡,取第一个符合条件的网卡 IP

但是有一下潜在的问题

  • 变量 ipv4 未提前初始化

    如果遍历全程没匹配到网卡,ipv4 会是 undefined,后续使用会报错。

  • 多网卡场景判断简陋

    电脑同时插网线 + 连 WiFi 双网卡时,只会取遍历顺序靠前的网卡 IP,无法指定网卡。

  • 没有过滤虚拟网卡(虚拟机、VPN、虚拟适配器)

    虚拟网卡的 internal 同样为 false,会被误判选中。

所以修改尝试函数的结构:

  try {
    const interfaces = os.networkInterfaces()
    for (const interfaceName of Object.keys(interfaces)) {
      for (const iface of interfaces[interfaceName]) {
        if (iface.family === 'IPv4' && !iface.internal) {
          ipv4 = iface.address
          break
        }
      }
      if (ipv4 !== '127.0.0.1') break
    }
  } catch (error) {
    console.error('[网络信息] 获取IPv4地址失败:', error)
  }

最后

app.listen(PORT, () => {
  const { ssid, ipv4, interfaceName, allIPs } = getNetworkInfo()
  console.log('='.repeat(64))
  console.log('TypeDance 打字训练平台 - 合并部署模式 - JTZJ')
  console.log('Designed by YeRanHvril(HAUITEUT)')
  console.log('='.repeat(64))
  console.log(`WiFi名称: ${ssid}`)
  console.log(`网卡名称: ${interfaceName}`)
  console.log(`IPv4地址: ${ipv4}`)
  if (allIPs.length > 1) {
    console.log('可用地址列表:')
    allIPs.forEach(c => {
      const tag = c.isWiFi ? '[WiFi]' : c.isPhysical ? '[物理]' : '[其他]'
      console.log(`  ${tag} ${c.ip} (${c.interface})`)
    })
  }
  console.log(`服务地址: http://localhost:${PORT}`)
  console.log(`局域网访问: http://${ipv4}:${PORT}/`)
  console.log(`前端页面: http://localhost:${PORT}/`)
  console.log(`管理后台: http://localhost:${PORT}/*******.html`)
  console.log(`API 接口: http://localhost:${PORT}/*******/`)
  console.log(`数据文件: ${DATA_FILE}`)
  console.log(`默认管理员: t************************************n`)
  console.log('密码由官方分发,请妥善保存')
  console.log('='.repeat(64))

  // 初始化令牌缓存
  initTokenCache()
})