2025-09-08 16:34:51 +08:00
|
|
|
|
const http = require('http');
|
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
const path = require('path');
|
|
|
|
|
|
const url = require('url');
|
|
|
|
|
|
|
|
|
|
|
|
const PORT = 4155;
|
|
|
|
|
|
const HOST = '0.0.0.0';
|
|
|
|
|
|
|
|
|
|
|
|
// MIME 类型映射
|
|
|
|
|
|
const mimeTypes = {
|
|
|
|
|
|
'.html': 'text/html; charset=utf-8',
|
|
|
|
|
|
'.css': 'text/css',
|
|
|
|
|
|
'.js': 'text/javascript',
|
|
|
|
|
|
'.json': 'application/json',
|
|
|
|
|
|
'.png': 'image/png',
|
|
|
|
|
|
'.jpg': 'image/jpeg',
|
|
|
|
|
|
'.jpeg': 'image/jpeg',
|
|
|
|
|
|
'.gif': 'image/gif',
|
|
|
|
|
|
'.svg': 'image/svg+xml',
|
|
|
|
|
|
'.ico': 'image/x-icon',
|
|
|
|
|
|
'.woff': 'font/woff',
|
|
|
|
|
|
'.woff2': 'font/woff2',
|
|
|
|
|
|
'.ttf': 'font/ttf',
|
|
|
|
|
|
'.eot': 'font/eot'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 创建服务器
|
|
|
|
|
|
const server = http.createServer((req, res) => {
|
2025-09-14 18:53:27 +08:00
|
|
|
|
// 记录请求
|
|
|
|
|
|
const timestamp = new Date().toLocaleString('zh-CN');
|
|
|
|
|
|
const clientIP = req.connection.remoteAddress || req.socket.remoteAddress;
|
|
|
|
|
|
console.log(`[${timestamp}] ${clientIP} -> ${req.method} ${req.url}`);
|
|
|
|
|
|
|
2025-09-08 16:34:51 +08:00
|
|
|
|
// 解析 URL
|
|
|
|
|
|
const parsedUrl = url.parse(req.url);
|
|
|
|
|
|
let pathname = decodeURIComponent(parsedUrl.pathname);
|
|
|
|
|
|
|
|
|
|
|
|
// 默认文件
|
|
|
|
|
|
if (pathname === '/') {
|
|
|
|
|
|
pathname = '/index.html';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 构建文件路径
|
|
|
|
|
|
const filePath = path.join(__dirname, pathname);
|
|
|
|
|
|
|
|
|
|
|
|
// 安全检查:确保文件路径在当前目录内
|
|
|
|
|
|
if (!filePath.startsWith(__dirname)) {
|
|
|
|
|
|
res.writeHead(403);
|
|
|
|
|
|
res.end('Forbidden');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查文件是否存在
|
|
|
|
|
|
fs.stat(filePath, (err, stats) => {
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
// 文件不存在
|
|
|
|
|
|
res.writeHead(404);
|
|
|
|
|
|
res.end('Not Found');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (stats.isDirectory()) {
|
|
|
|
|
|
// 如果是目录,尝试加载 index.html
|
|
|
|
|
|
const indexPath = path.join(filePath, 'index.html');
|
|
|
|
|
|
fs.stat(indexPath, (err, stats) => {
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
res.writeHead(404);
|
|
|
|
|
|
res.end('Not Found');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
serveFile(indexPath, res);
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 提供文件
|
|
|
|
|
|
serveFile(filePath, res);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 提供文件的函数
|
|
|
|
|
|
function serveFile(filePath, res) {
|
|
|
|
|
|
const ext = path.extname(filePath);
|
|
|
|
|
|
const contentType = mimeTypes[ext] || 'application/octet-stream';
|
|
|
|
|
|
|
|
|
|
|
|
fs.readFile(filePath, (err, content) => {
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
res.writeHead(500);
|
|
|
|
|
|
res.end('Internal Server Error');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res.writeHead(200, { 'Content-Type': contentType });
|
|
|
|
|
|
res.end(content);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-14 18:53:27 +08:00
|
|
|
|
// 获取本地IP地址
|
|
|
|
|
|
function getLocalIP() {
|
|
|
|
|
|
const os = require('os');
|
|
|
|
|
|
const interfaces = os.networkInterfaces();
|
|
|
|
|
|
|
|
|
|
|
|
for (const name of Object.keys(interfaces)) {
|
|
|
|
|
|
for (const iface of interfaces[name]) {
|
|
|
|
|
|
// 跳过内部(即127.0.0.1)和非IPv4地址
|
|
|
|
|
|
if (iface.family === 'IPv4' && !iface.internal) {
|
|
|
|
|
|
return iface.address;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return 'localhost';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-08 16:34:51 +08:00
|
|
|
|
// 启动服务器
|
|
|
|
|
|
server.listen(PORT, HOST, () => {
|
2025-09-14 18:53:27 +08:00
|
|
|
|
const localIP = getLocalIP();
|
|
|
|
|
|
|
2025-09-08 16:34:51 +08:00
|
|
|
|
console.log('======================================');
|
2025-09-14 18:53:27 +08:00
|
|
|
|
console.log(' Web Result 静态服务器启动成功');
|
2025-09-08 16:34:51 +08:00
|
|
|
|
console.log('======================================');
|
2025-09-14 18:53:27 +08:00
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('🏠 本地访问:');
|
|
|
|
|
|
console.log(` http://localhost:${PORT}`);
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
|
|
|
|
|
|
if (localIP !== 'localhost') {
|
|
|
|
|
|
console.log('🌐 局域网访问:');
|
|
|
|
|
|
console.log(` http://${localIP}:${PORT}`);
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('📱 移动设备访问:');
|
|
|
|
|
|
console.log(` http://${localIP}:${PORT}`);
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('[提示] 服务器监听所有网络接口 (0.0.0.0)');
|
|
|
|
|
|
console.log('[提示] 按 Ctrl+C 停止服务器');
|
|
|
|
|
|
console.log('');
|
|
|
|
|
|
console.log('等待请求...');
|
2025-09-08 16:34:51 +08:00
|
|
|
|
});
|