当前位置: 首页 > news >正文

用 Node.js 原生 API 写个本地代理,解决跨域烦恼

用 Node.js 原生 API 写个本地代理,解决跨域烦恼

前后端分离开发时,最让人头疼的往往不是业务逻辑,而是浏览器的同源策略。前端跑在localhost:3000,后端在localhost:8080,一旦前端发起 AJAX 请求,控制台立马飘红,CORS 报错拦路。

很多同事为了省事,直接在后台配置Access-Control-Allow-Origin: *。这在本地调试没问题,但上线前如果忘了收回来,生产环境就是个大漏洞。与其在两边反复横跳改配置,不如在本地起个轻量级的代理网关。用 Node.js 原生http模块就能写,零依赖,还能顺便把请求头给洗了。

为什么需要这个代理

本地开发时,前后端端口不同,浏览器默认禁止跨域访问。

如果不做处理,前端请求会被拦截。如果为了图方便在后端直接放行所有跨域,又会给生产环境埋下 XSS 隐患。更麻烦的是,没有中间层,你很难统一查看请求的转发耗时,排查问题全靠猜。

这个代理的作用很简单:前端请求先发给它,它再转给后端。浏览器以为是在跟同源服务器通信,自然就放行了。

代理是怎么工作的

流程并不复杂,核心就是“截获 - 重写 - 转发”。

  1. 截获请求:前端请求localhost:9000,代理程序接收到。
  2. 重写头部:把OriginHost等头部改成后端能识别的样子,避免后端微服务因为校验 Origin 而拒绝请求。
  3. 转发请求:代理向后端localhost:8080发起真实的 HTTP 请求。
  4. 注入响应头:拿到后端返回的数据后,手动加上Access-Control-Allow-Origin: *等跨域头。
  5. 返回前端:把处理好的数据流式写回给前端。

如果后端 5 秒内没反应,代理直接返回 504,避免前端页面卡死。

代码实现

下面这个脚本完全基于 Node.js 原生httpurl模块,没有引入http-proxy-middleware这种第三方包。代码量不大,但包含了超时控制、流式转发和基础的路由处理。

// dev_proxy_gateway.js const http = require('http'); const url = require('url'); const TARGET_API_SERVER = 'http://127.0.0.1:8080'; // 后端真实地址 const PROXY_PORT = 9000; // 代理监听端口 function logging(msg) { console.log(`\x1b[36m[Proxy] ${msg}\x1b[0m`); } const server = http.createServer((req, res) => { logging(`${req.method} ${req.url}`); // 1. 处理 OPTIONS 预检请求 if (req.method === 'OPTIONS') { res.writeHead(204, { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400' }); return res.end(); } // 2. 构造转发请求 const parsedTarget = url.parse(TARGET_API_SERVER); const options = { hostname: parsedTarget.hostname, port: parsedTarget.port, path: req.url, method: req.method, headers: { ...req.headers, host: `${parsedTarget.hostname}:${parsedTarget.port}`, origin: TARGET_API_SERVER, referer: TARGET_API_SERVER }, timeout: 5000 // 5 秒超时 }; // 3. 发起代理请求 const proxyReq = http.request(options, (proxyRes) => { // 注入跨域头 res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.writeHead(proxyRes.statusCode, proxyRes.headers); // 4. 流式透传数据 proxyRes.pipe(res); }); // 5. 错误与超时处理 proxyReq.on('error', (err) => { logging(`Error: ${err.message}`, 'error'); res.writeHead(504, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Gateway Timeout: Backend unreachable.' })); }); proxyReq.on('timeout', () => { proxyReq.destroy(); res.writeHead(504, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Gateway Timeout: Backend no response within 5s.' })); }); // 把前端的数据管道写入代理请求 req.pipe(proxyReq); }); server.listen(PROXY_PORT, () => { logging(`Proxy running on http://127.0.0.1:${PROXY_PORT}`); logging(`Forwarding to: ${TARGET_API_SERVER}`); });

几个需要注意的地方

这套方案虽然轻量,但在实际使用中也有几个局限性,得提前心里有数:

  1. 延迟问题:请求多了一层转发,理论上会增加几毫秒的延迟。但在本地环境下,这点损耗(通常 <5ms)相比解决跨域带来的便利,完全可以忽略。
  2. HTTPS 支持:如果前端项目强制 HTTPS,代理网关也得配自签名证书。本地调试建议在浏览器里直接允许“不安全连接”,没必要为了个开发工具去折腾复杂的证书链。
  3. 长连接支持:上面的代码只处理了普通的 HTTP 请求。如果项目里有 WebSocket 或 SSE(服务端推送),原生http模块不会自动升级协议。这时候需要显式监听upgrade事件,手动把 TCP socket 桥接过去,否则实时功能会失效。

总结

在本地起个 Node.js 代理,是解决跨域最稳妥的办法。它比在后端直接放行安全,比配 Nginx 轻量。代码不多,维护成本低,能帮你把精力从“为什么请求被拦截”这种琐事上解放出来,专心写业务逻辑。

http://www.gsyq.cn/news/1596252.html

相关文章:

  • Windows 系统文件d3dx9_38.dll丢失找不到问题解决
  • ArkUI(轮播图,图片)组件介绍
  • DevCloud 预置镜像避坑指南与 ROCm 版本锁定
  • Blender UV编辑终极指南:UvSquares插件让复杂网格一键变规整
  • JL-34 超声波一体式气象站 轻松搞定多要素环境监测
  • 编写 Python 脚本快速诊断 AMD GPU 健康状态
  • 短信平台的数据监控架构设计
  • 告别文字墙!TokUI让AI渲染像刷短视频一样丝滑
  • 口碑超棒!这家电动无轨龙门架制造厂家究竟有何过人之处?
  • 蛋仔网:独立游戏资源网站怎么选,授权和来源先看清
  • 40 英镑的 Xteink X4 电子墨水阅读器:小巧便携,自定义固件让阅读体验升级!
  • 终极AMD Ryzen处理器调试指南:硬件性能调优与系统监控完整教程
  • Spring Boot应用内存安全实战:从Heap Dump中检测与防护数据库密码泄露
  • Logstash:数据管道处理工具,14k Star
  • 全志H6开发板设计:从硬件到软件的嵌入式开发实践
  • 3000元以内手机怎么选?这4款性价比之王闭眼入
  • Windows系统文件d3dx10_35.dll丢失找不到问题解决
  • FastAPI 新手入门第 1 篇:第一个接口
  • 对Harness的理解
  • DSP28335最小系统设计:硬件要点与工程实践
  • 根据您提供的规则,已为您生成一条符合要求的CSDN标题:临沂GEO服务技术解析与方案考量
  • 外区域拉格朗日平均曲率方程:存在性、渐近行为与核心分析策略
  • 喜报丨实力加冕!盘古信息荣获2025年度广东省科学技术奖科技进步一等奖
  • 杰理之IO在上电后又被Deinit,导致没有保持住IO电平【篇】
  • 205-协程与 Flow 入门
  • Windows Btrfs完全指南:如何在Windows上使用下一代Linux文件系统
  • ARM Cortex‑M7 处理器架构技术详解
  • 极化码SO-FSCL解码:原理、硬件实现与性能优化
  • Apple Container 快速入门
  • 445. Java 正则表达式 - 边界匹配器