跨子网URL重定向:仅开放含/xyz/路径的Computer1访问
问题场景
网络环境
- Computer1:IP
192.168.10.1,子网掩码255.255.255.0,无互联网访问权限 - Computer2:IP
192.168.1.1,子网掩码255.255.255.0 - Router1:配置双IP
192.168.1.200、192.168.10.200 - Router2:IP
192.168.1.254,已接入互联网
核心需求
从广域网访问Computer1的192.168.10.1/xyz/urlxyz.html,需满足:
- 仅放行包含
/xyz/的URL请求 - 禁止暴露
192.168.10.x子网及Computer1上的其他服务 - 不使用VPN、代理类工具(仅通过现有网络节点实现)
尝试方案及问题
在Computer2上部署Node.js转发服务,但因使用已废弃的request库,且未完整处理请求头、请求体,导致页面报错(仅打印机场景可用):
app.get('/xyz/',function(req,res){ request.get("http://192.168.10.1"+req.originalUrl).on('error', function(err) { console.error(err) }).pipe(res); }); //request is a deprecated library
解决方案
替换废弃库,实现完整请求转发
使用Node.js原生http模块(无额外依赖)或axios重构转发逻辑,确保请求头、请求体、响应完整传递,同时严格限制路径范围。
方案1:原生http模块实现
const express = require('express'); const http = require('http'); const app = express(); // 解析所有类型的请求体,支持POST/PUT等带数据的请求 app.use(express.raw({ type: '*/*' })); // 仅处理/xyz/开头的所有请求方法 app.all('/xyz/*', (req, res) => { // 构造转发到Computer1的请求参数 const targetOpts = { hostname: '192.168.10.1', port: 80, path: req.originalUrl, method: req.method, headers: { // 复制原请求头,替换host为目标主机IP ...req.headers, host: '192.168.10.1' } }; // 发起代理请求 const proxyReq = http.request(targetOpts, (proxyRes) => { // 同步响应状态码和响应头 res.writeHead(proxyRes.statusCode, proxyRes.headers); // 流式转发响应体 proxyRes.pipe(res); }); // 处理代理请求错误 proxyReq.on('error', (err) => { console.error('转发失败:', err); res.status(500).send('转发服务出错'); }); // 流式转发请求体(针对带数据的请求) req.pipe(proxyReq); }); // 监听80端口(需在Router2配置端口映射:WAN端口→Computer2的80端口) app.listen(80, () => { console.log('代理服务已启动'); });
方案2:axios实现(需先执行npm install axios)
const express = require('express'); const axios = require('axios'); const app = express(); app.use(express.raw({ type: '*/*' })); app.all('/xyz/*', async (req, res) => { try { const targetUrl = `http://192.168.10.1${req.originalUrl}`; // 完整转发请求信息 const proxyRes = await axios({ url: targetUrl, method: req.method, headers: { ...req.headers, host: '192.168.10.1' }, data: req.body, responseType: 'stream' }); // 同步响应头 res.set(proxyRes.headers); // 流式返回响应内容 proxyRes.data.pipe(res); } catch (err) { console.error('转发失败:', err); res.status(err.response?.status || 500).send(err.message || '转发服务出错'); } }); app.listen(80, () => { console.log('代理服务已启动'); });
关键配置说明
- Router2端口映射:必须在Router2上配置端口映射,将广域网请求的目标端口(如80)转发到Computer2的监听端口(示例中为80),否则WAN请求无法到达代理服务。
- 路径严格控制:通过
/xyz/*路由规则,确保仅转发以/xyz/开头的请求,完全符合需求中限制访问范围的要求。 - 请求头处理:复制原请求头并替换
host字段,避免Computer1因host不匹配拒绝请求。 - 多请求方法支持:使用
app.all替代app.get,确保POST、PUT等带交互的请求也能正常转发。
内容的提问来源于stack exchange,提问作者Trigun
相关产品推荐
相关产品推荐

