server.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // server.js —— 零依赖反向代理版
  2. const http = require('http');
  3. const https = require('https');
  4. const fs = require('fs');
  5. const path = require('path');
  6. const url = require('url');
  7. const ROOT = path.join(__dirname, 'dist', 'h5');
  8. const PORT = process.env.PORT || 3000;
  9. const REMOTE = 'http://101.43.219.60:7700';
  10. const mime = { '.html': 'text/html', '.js': 'application/javascript', '.css': 'text/css', '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml', '.ico': 'image/x-icon' };
  11. /* ------- 代理函数 ------- */
  12. function proxyToRemote(req, res) {
  13. const parsed = url.parse(req.url); // /dr/xxx?query
  14. const path = parsed.path;
  15. const target = url.parse(REMOTE);
  16. const options = {
  17. hostname: target.hostname,
  18. port: target.port || (target.protocol === 'https:' ? 443 : 80),
  19. path: path + (parsed.search || ''),
  20. method: req.method,
  21. headers: { ...req.headers } // 原样带过去
  22. };
  23. // 删除本地头,避免 host 不匹配
  24. delete options.headers.host;
  25. delete options.headers.origin;
  26. delete options.headers.referer;
  27. console.log('Options:', options);
  28. console.log('Path:', options.path);
  29. const proxyReq = (target.protocol === 'https:' ? https : http).request(options, (proxyRes) => {
  30. // 把远端响应头原样写给浏览器
  31. res.writeHead(proxyRes.statusCode, proxyRes.headers);
  32. proxyRes.pipe(res);
  33. }).on('error', e => {
  34. console.error('[proxy error]', e.message);
  35. res.writeHead(502).end('Bad Gateway');
  36. });
  37. req.pipe(proxyReq); // 把浏览器发来的 body 也转发过去
  38. }
  39. /* ------- 静态文件服务函数 ------- */
  40. function serveStatic(req, res) {
  41. let file = decodeURIComponent(req.url.split('?')[0]);
  42. file = file === '/' ? '/index.html' : file;
  43. const filePath = path.join(ROOT, file);
  44. if (!filePath.startsWith(ROOT)) return res.writeHead(403).end('Forbidden');
  45. fs.readFile(filePath, (err, data) => {
  46. if (err) {
  47. if (file !== '/index.html') {
  48. fs.readFile(path.join(ROOT, 'index.html'), (e, d) => {
  49. if (e) return res.writeHead(500).end('Server Error');
  50. res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(d);
  51. });
  52. } else res.writeHead(404).end('Not Found');
  53. return;
  54. }
  55. const ext = path.extname(filePath);
  56. res.writeHead(200, { 'Content-Type': mime[ext] || 'application/octet-stream' });
  57. res.end(data);
  58. });
  59. }
  60. /* ------- 主入口 ------- */
  61. http.createServer((req, res) => {
  62. // 处理日志请求--纪录
  63. if (req.method === 'POST' && req.url === '/log') {
  64. let body = '';
  65. req.on('data', chunk => body += chunk);
  66. req.on('end', () => {
  67. try {
  68. const { level, msg } = JSON.parse(body);
  69. writeLog(level, msg);
  70. } catch { }
  71. res.writeHead(204);
  72. res.end();
  73. });
  74. return;
  75. }
  76. // 1. 预检直接 200
  77. if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; }
  78. // 2. 路径以 /dr 开头 → 代理
  79. if (req.url.startsWith('/dr')) { proxyToRemote(req, res); return; }
  80. // 3. 其它 → 静态文件
  81. serveStatic(req, res);
  82. }).listen(PORT, () => console.log(`> H5 running at http://localhost:${PORT}`));