下面是一个完整的指南,教你如何从零开始构建一个Node.js服务来托管前端项目,并代理API请求到其他服务器。

1. 项目初始化

# 创建项目目录
mkdir node-proxy-server
cd node-proxy-server# 初始化npm项目
npm init -y# 安装必要依赖
npm install express http-proxy-middleware compression cors morgan
npm install nodemon --save-dev

2. 基础服务器配置

创建 server.js 文件:

const express = require('express')
const path = require('path')
const { createProxyMiddleware } = require('http-proxy-middleware')
const compression = require('compression')
const cors = require('cors')
const morgan = require('morgan')const app = express()
const PORT = process.env.PORT || 3000// 中间件配置
app.use(compression()) // 启用gzip压缩
app.use(cors()) // 跨域支持
app.use(morgan('dev')) // 请求日志// 静态文件服务 - 托管前端构建产物
app.use(express.static(path.join(__dirname, 'dist')))// API代理配置
const apiProxy = createProxyMiddleware({target: 'http://api.your-backend.com', // 你的后端API地址changeOrigin: true,pathRewrite: {'^/api': '' // 移除/api前缀},onProxyReq: (proxyReq, req, res) => {// 可以在这里添加请求头等操作console.log(`代理请求: ${req.method} ${req.path} -> ${proxyReq.path}`)},onError: (err, req, res) => {console.error('代理错误:', err)res.status(500).json({ error: '代理请求失败' })}
})// 应用代理中间件
app.use('/api', apiProxy)// 处理前端路由 - 所有未匹配的请求返回index.html
app.get('*', (req, res) => {res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})// 启动服务器
app.listen(PORT, () => {console.log(`服务器运行在 http://localhost:${PORT}`)console.log(`代理API请求到: http://api.your-backend.com`)
})

3. 前端项目构建与部署

假设你有一个Vue/React前端项目:

  1. 构建前端项目:
# 在Vue项目中
npm run build# 或React项目中
npm run build
  1. 将构建产物复制到Node.js项目:
# 从Vue项目
cp -R your-vue-project/dist ./node-proxy-server/# 或从React项目
cp -R your-react-project/build ./node-proxy-server/dist

4. 环境变量配置

创建 .env 文件:

PORT=3000
API_BASE_URL=http://api.your-backend.com
NODE_ENV=production

修改 server.js 使用环境变量:

require('dotenv').config()// 更新代理配置
const apiProxy = createProxyMiddleware({target: process.env.API_BASE_URL || 'http://api.your-backend.com',// ...其他配置不变
})

5. 高级代理配置

多API端点代理

// 用户服务
app.use('/api/user', createProxyMiddleware({target: 'http://user-service.your-backend.com',changeOrigin: true,pathRewrite: { '^/api/user': '' }
}))// 订单服务
app.use('/api/order', createProxyMiddleware({target: 'http://order-service.your-backend.com',changeOrigin: true,pathRewrite: { '^/api/order': '' }
}))

WebSocket代理

const wsProxy = createProxyMiddleware('/ws', {target: 'ws://your-websocket-server.com',ws: true,changeOrigin: true,logLevel: 'debug'
})app.use(wsProxy)

6. 安全增强

const helmet = require('helmet')// 添加安全头
app.use(helmet())// 限制请求体大小
app.use(express.json({ limit: '10kb' }))
app.use(express.urlencoded({ extended: true, limit: '10kb' }))// 速率限制
const rateLimit = require('express-rate-limit')
const limiter = rateLimit({windowMs: 15 * 60 * 1000, // 15分钟max: 100 // 每个IP限制100个请求
})
app.use(limiter)

7. 开发与生产配置

package.json脚本

{"scripts": {"start": "node server.js","dev": "nodemon server.js","test": "echo \"Error: no test specified\" && exit 1"}
}

开发模式热重载

if (process.env.NODE_ENV === 'development') {const chokidar = require('chokidar')const watcher = chokidar.watch('./dist')watcher.on('ready', () => {watcher.on('all', () => {console.log('检测到前端文件变化,清除模块缓存...')Object.keys(require.cache).forEach(id => {if (id.includes('/dist/')) delete require.cache[id]})})})
}

8. 完整项目结构

node-proxy-server/
├── dist/                    # 前端构建产物
│   ├── index.html
│   ├── static/
│   └── ...
├── server.js                # 主服务器文件
├── .env                     # 环境变量
├── .gitignore
└── package.json

9. 部署指南

PM2生产环境部署

npm install pm2 -g
pm2 start server.js --name "node-proxy"
pm2 save
pm2 startup

Docker部署

创建 Dockerfile:

FROM node:16-alpineWORKDIR /appCOPY package*.json ./
RUN npm install --productionCOPY . .ENV PORT=3000
ENV NODE_ENV=productionEXPOSE 3000CMD ["node", "server.js"]

构建并运行:

docker build -t node-proxy .
docker run -d -p 3000:3000 --name node-proxy node-proxy

10. 测试与验证

  1. 启动服务器:
npm run dev
  1. 验证静态文件服务:
    访问 http://localhost:3000 应该看到你的前端应用

  2. 验证API代理:
    访问 http://localhost:3000/api/some-endpoint 应该代理到你的后端服务

  3. 验证前端路由:
    刷新非根路由(如 http://localhost:3000/about)应该正确返回index.html

常见问题解决

  1. 代理不工作:

    • 检查目标服务器是否可访问
    • 检查代理路径配置是否正确
    • 查看服务器日志中的错误信息
  2. 前端路由问题:

    • 确保所有路由都返回index.html
    • 检查前端路由模式(history vs hash)
  3. 跨域问题:

    • 确保正确配置了CORS中间件
    • 检查代理是否正确地修改了Origin头

这个Node.js代理服务器提供了完整的解决方案,包括:

  • 静态文件服务
  • API请求代理
  • 开发与生产环境支持
  • 安全增强
  • 部署选项

你可以根据实际需求进一步定制和扩展这个基础架构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912042.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912042.shtml
英文地址,请注明出处:http://en.pswp.cn/news/912042.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lynx vs React Native vs Flutter 全面对比:三大跨端框架实测分析

一文看懂三大热门跨端技术的历史渊源、架构机制、开发体验、包体积对比与性能评估。 我陪你用实测数据带你理性选型,不踩坑,不盲信。 1. 框架简介:它们是谁?来自哪里?干嘛用? 框架名称所属公司发布时间初衷…

CKESC的ROCK 180A-H 无人机电调:100V 高压冗余设计与安全保护解析

一、核心技术参数与性能指标 电压范围:支持 12~26S 锂电(适配 110V 高压系统)电流特性: 持续工作电流:90A(特定散热条件)瞬时耐流(1 秒):220A,3 …

优化 ArcPy 脚本性能

使用并行处理 如果硬件条件允许,可以使用 Python 的并行处理模块(如 multiprocessing)来同时处理多个小任务。这样可以充分利用多核处理器的优势,提高脚本的执行效率。 import multiprocessing def process_raster(raster):arcpy…

Windows下CMake通过鸿蒙SDK交叉编译三方库

前言 华为鸿蒙官方的文章CMake构建工程配置HarmonyOS编译工具链 中介绍了在Linux平台下如何使用CMake来配置鸿蒙的交叉编译环境,编译输出在Harmony中使用的第三方so库以及测试demo。 本文主要是在Windows下实现同样的操作。由于平台差异的原因,有些细节…

从C学C++(6)——构造函数和析构函数

从C学C(6)——构造函数和析构函数 若无特殊说明,本博客所执行的C标准均为C11. 构造函数与析构函数 构造函数定义 构造函数是特殊的成员函数,当创建类类型的新对象,系统自动会调用构造函数构造函数是为了保证对象的每个数据成员都被正确初…

清理 Windows C 盘该注意什么

C 盘空间不足会严重影响系统性能。 清理 C 盘文件时,首要原则是安全。错误地删除系统文件会导致 Windows 无法启动。下面我将按照 从最安全、最推荐到需要谨慎操作的顺序,为你详细列出可以清理的文件和文件夹,并提供操作方法。 第一梯队&…

Python Selenium 滚动到特定元素

文章目录 Python Selenium 滚动到特定元素⚙️ **1. 使用 scrollIntoView() 方法(最推荐)**🖱️ **2. 结合 ActionChains 移动鼠标(模拟用户行为)**🧩 **3. 使用坐标计算滚动(精确控制像素&…

你写的 Express 接口 404,可能是被“动态路由”吃掉了

本文首发在我的个人博客:你写的 Express 接口 404,可能是被“动态路由”吃掉了 前情提要 最近参与公司的一个项目前端 React,后端用的 Express。目前我就做一些功能的新增或者修改。 对于 Express ,本人没有公司项目实战经验&…

【Java面试】你是怎么控制缓存的更新?

🔄 一、数据实时同步失效(强一致性) 原理:数据库变更后立即失效或更新缓存,保证数据强一致。 实现方式: Cache Aside(旁路缓存): 读流程:读缓存 → 未命中则…

react-嵌套路由 二级路由

什么是嵌套路由? 在一级路由中又内嵌了其他路由,这种关系就叫做嵌套路由,嵌套至一级路由内的路由又称作二级路由 嵌套路由配置 实现步骤 配置二级路由 children嵌套 import Login from "../page/Login/index"; import Home from …

【CMake基础入门教程】第八课:构建并导出可复用的 CMake 库(支持 find_package() 查找)

很好!我们进入 第八课:构建并导出可复用的 CMake 库(支持 find_package() 查找)。 🎯 本课目标 你将掌握: 如何构建一个库并通过 install() 导出其配置; 如何让别人在项目中使用 find_package…

Jenkins与Kubernetes深度整合实践

采用的非jenkins-slave方式 jenkins配置: Jenkins添加k8s master节点的服务器信息 在Jenkins容器内部与k8s master节点设置免费登录 # docker过滤查询出运行的Jenkins服务 $ docker ps | grep jenkins# 进入Jenkins容器内部 $ docker exec -it jenkins-server /bi…

GraphQL API-1

简介 判断GraphQL方式 判断一个网站是否使用了GraphQL API,可以通过以下几种方法: 1. 检查网络请求 查看请求端点 GraphQL 通常使用单一端点,常见路径如: /graphql/api/graphql/gql/query 观察请求特征 POST 请求为主&…

推荐C++题目练习网站

LeetCode LeetCode是一个全球知名的编程练习平台,提供大量C题目,涵盖数据结构、算法、系统设计等。题目难度从简单到困难,适合不同水平的学习者。平台支持在线编写代码并即时运行测试,提供详细的题目讨论区和官方解答。 Codeforc…

Spring Cloud 微服务(服务注册与发现原理深度解析)

📌 摘要 在微服务架构中,服务注册与发现是整个系统运行的基础核心模块。它决定了服务如何被定位、调用和管理。 本文将深入讲解 Spring Cloud 中 Eureka 的服务注册与发现机制,从底层原理到源码分析,再到实际开发中的最佳实践&a…

【Linux 设备模型框架 kobject 和 kset】

Linux 设备模型框架 kobject 和 kset 一、Linux 设备模型概述二、kobject 与 kset 的核心概念1. kobject2. kset3. 关键数据结构 三、kobject 与 kset 的实现源码四、源码解析与使用说明1. kset 的创建与初始化2. kobject 的创建与属性3. sysfs 属性操作4. 用户空间访问示例 五…

一起学前端之HTML------(1)HTML 介绍

HTML 介绍 HTML 即超文本标记语言(HyperText Markup Language),它是构成网页的基础技术之一。HTML 借助各种标签(Tag)对网页的结构与内容加以描述。下面为你介绍其核心要点: 关键特性 标签结构&#xff…

整体迁移法迁移 Docker 镜像

docker添加了新的镜像数据盘,数据盘迁移步骤 使用整体迁移法迁移 Docker 镜像后,可以在确认迁移成功且新数据盘正常使用后,删除旧数据目录来释放空间1。 # 停止 Docker 服务 sudo systemctl stop docker # 停止 socket 监听器 sudo systemct…

智能IDE+高效数据采集,让数据获取接近0门槛

亮数据也有了自己的官方账号,大家可以关注:https://brightdata.blog.csdn.net/ 现在正有福利,有兴趣的伙伴可以访问链接: https://www.bright.cn/products/web-scraper/?utm_sourcebrand&utm_campaignbrnd-mkt_cn_csdn_jhx…

GNSS位移监测站在大坝安全中的用处

一、实时监测大坝变形 整体位移监测 GNSS(全球导航卫星系统)位移监测站能够实时、连续地获取大坝在三维空间中的位置信息,包括水平位移和垂直位移。大坝在长期运行过程中,受到水压力、温度变化、地基沉降等多种因素的影响&#x…