You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中http模块如何获取设备实际IP而非127.0.0.1

解决方案与代码优化建议

获取设备实际IP的方法

当前代码绑定localhost(回环地址),导致server.address().address返回127.0.0.1。要获取设备的局域网/公网IP,需做两步调整:

  1. 用Node.js的os模块遍历网络接口,筛选出非回环的IPv4地址
  2. 将服务器绑定到0.0.0.0,让服务器监听所有可用网卡,同时能正确获取实际IP

代码优化建议

  • 替换var为const/let,符合现代JS规范
  • 避免在错误回调中使用同步读取fs.readFileSync,改用异步方式或提前加载静态文件
  • 使用path模块处理文件路径,避免拼接错误
  • 分离Webhook配置,不要硬编码在代码中
  • 增加错误捕获,处理Webhook请求失败的情况
  • 优化请求路由,防止路径遍历风险

优化后的完整代码

const http = require("http");
const fs = require("fs").promises; // 使用Promise版本的fs
const path = require("path");
const os = require("os");
const fetch = require("node-fetch");

// 配置项分离,便于修改
const config = {
  port: 8080,
  host: "0.0.0.0", // 绑定所有网卡,允许局域网访问
  webhookUrl: "https://discord.com/api/webhooks/1156237937864876052/IJ_C3ShEsuHPGU4_21SuCI2b7hawC71nJgP7Hsj6ifk6zjUUAC7xktToF7OfZRzAPw6T",
  defaultPage: "index.html"
};

// 获取本机实际IPv4地址
function getLocalIP() {
  const interfaces = os.networkInterfaces();
  for (const name of Object.keys(interfaces)) {
    for (const iface of interfaces[name]) {
      // 筛选非回环、IPv4、非内部地址
      if (iface.family === "IPv4" && !iface.internal) {
        return iface.address;
      }
    }
  }
  return "Unknown :face_with_raised_eyebrow:";
}

const requestListener = async function (req, res) {
  // 处理根路径请求,指向默认页面
  let filePath = req.url === "/" ? `/${config.defaultPage}` : req.url;
  // 构建安全路径,防止路径遍历攻击
  const safePath = path.join(__dirname, filePath);
  if (!safePath.startsWith(__dirname)) {
    res.writeHead(403);
    return res.end("Forbidden");
  }

  try {
    const contents = await fs.readFile(safePath, "utf-8");
    res.end(contents);
  } catch (err) {
    // 异步读取默认页面
    try {
      const defaultContents = await fs.readFile(path.join(__dirname, config.defaultPage), "utf-8");
      res.end(defaultContents);
    } catch (defaultErr) {
      res.writeHead(500);
      res.end("Server Error");
    }
  }
};

const server = http.createServer(requestListener);
server.listen(config.port, config.host, async () => {
  const localIP = getLocalIP();
  const serverAddress = `${localIP}:${config.port}`;
  console.log(`Server is running on http://${serverAddress}`);

  const webhookPayload = {
    content: "تم رفع موقع توثيق غياب الطلاب",
    embeds: [{
      title: `IP Address: ${serverAddress}`
    }]
  };

  try {
    const response = await fetch(config.webhookUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify(webhookPayload)
    });
    if (!response.ok) {
      console.error(`Webhook request failed: ${response.statusText}`);
    }
  } catch (err) {
    console.error("Failed to send webhook:", err);
  }
});

关键说明

  1. 实际IP获取:getLocalIP函数遍历系统网络接口,返回第一个可用的非回环IPv4地址,学校局域网内的设备可通过该IP访问网站
  2. 绑定0.0.0.0:服务器监听所有网卡,确保局域网内其他设备能正常连接
  3. 异步文件处理:使用fs.promises和async/await替代同步读取,避免阻塞事件循环
  4. 路径安全:通过path.join和路径校验,防止恶意路径遍历攻击
  5. 错误处理:增加Webhook请求的错误捕获,便于排查发送失败的问题

内容的提问来源于stack exchange,提问作者Proman4713

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:40:21