從零構建Node.js服務托管前端項目

下面是一個完整的指南,教你如何從零開始構建一個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…