Node.js中http模块如何获取设备实际IP而非127.0.0.1
解决方案与代码优化建议
获取设备实际IP的方法
当前代码绑定localhost(回环地址),导致server.address().address返回127.0.0.1。要获取设备的局域网/公网IP,需做两步调整:
- 用Node.js的
os模块遍历网络接口,筛选出非回环的IPv4地址 - 将服务器绑定到
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); } });
关键说明
- 实际IP获取:
getLocalIP函数遍历系统网络接口,返回第一个可用的非回环IPv4地址,学校局域网内的设备可通过该IP访问网站 - 绑定0.0.0.0:服务器监听所有网卡,确保局域网内其他设备能正常连接
- 异步文件处理:使用
fs.promises和async/await替代同步读取,避免阻塞事件循环 - 路径安全:通过
path.join和路径校验,防止恶意路径遍历攻击 - 错误处理:增加Webhook请求的错误捕获,便于排查发送失败的问题
内容的提问来源于stack exchange,提问作者Proman4713
相关产品推荐
相关产品推荐

