[TOC]
> 具體可以查看我的《React HandBook》-部署章節
# 簡介
在開發中大型的JavaEE項目時,前后端分離的框架逐漸成為業界的主流,傳統的單機部署前后端在同一個項目中的工程項目越來越少。這類JavaWeb項目的后端通常都采用微服務的架構,后端會被分解為諸多個小項目,然后使用dubbo+zookeeper或者springCloud來構建微服務,前端則會是一個單獨的項目,前臺的請求通過微服務來調用。但是,不同與傳統的web項目,這類前后端分離的項目如何在開發中部署和運行呢?
## 前后端的工作
前端的工作:實現整一個前端頁面以及交互邏輯,以及利用ajax與nodejs服務器(中間層)交互。
后端的工作:提供API接口,利用redis來管理session,與數據庫交互。
## RESTful Api和Json搭建前后臺交互

實現前后端分離,可以讓前后端獨立開發、獨立部署、獨立單測,雙方通過JSON進行數據交互。
對于前端開發人員來說,不用每次調試都需要啟動或配置Java/Tomcat運行環境;對于后端開發人員來說 ,也不用在需要往JSP頁面注入數據。
# 如何在開發時部署和運行前后端分離的JavaWeb項目
當前后端分離時,后端項目一定會被加載到tomcat的webapp目錄下面,但是前端的資源院該如何被訪問到呢?這里以tomcat這個中間件為例,探討在開發這類項目的時候,如何讓前后端分離的項目部署并且運行起來,即后端項目部署在tomcat之后如何在運行時訪問靜態資源(非上線部署)。
主要有兩種方案:
1. 在本地通過Nginx、Node來處理這些靜態資源。
2. 將靜態資源統一放入一個javaweb應用中,并將自動生成的war包隨后端項目一期丟入tomcat。
下面詳細介紹:
## 一、使用 Nginx 來訪問靜態資源。
在本地安裝 nginx 并且修改`nginx.conf`,修改相關配置,將 web 訪問的端口的資源進行更改,配置如下:
~~~
...
server {
listen 80;
server_name localhost;
charset utf-8;
#access_log logs/host.access.log main;
location / {
proxy_pass http://tomcat_pool;
proxy_redirect off;
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css|woff|woff2|ttf|eot|map)$ {
root D:\Workspaces\esop-html;
index index.html;
}
...
~~~
listen對象改為你本地的tomcat訪問端口,最下面location中的root改為你前端項目中靜態資源的位置,這樣就可以實現只部署后端的項目就能訪問前端的頁面了。
## 二、將前端項目轉換為動態的web項目,隨后端項目一起丟入tomcat
這個方案省去了在本地安裝和配置nginx,但是也只適用于開發階段項目的部署運行和調試,**真正在生產環境通常前后端項目會部署在不同的服務器**。
* 如果是Intellij Idea,在導入前端項目之后,右鍵項目 add framework support --> web application,這時將會把前端項目轉換為一個javaweb項目,然后將靜態資源放在生成的web目錄下即可。
* 如果是eclipse,可以新建一個javaweb項目然后將靜態資源放入web或者webcontent目錄下,或者直接先導入前端項目,然后通過 project facts 將項目轉換為dynamic web項目并勾選 js等相關配置。
然后,運行項目時把后端的war包和前端的war包一同添加到 deployment中運行即可。
# node部署前端
通過 nginx 來部署前端代碼,可以幫助前端實現以下基本需求:
1. 請求轉發,解決請求跨域的問題
2. gzip 請求壓縮
網站開啟 gzip 壓縮,不僅能夠節省帶寬,也能夠快速響應用戶的訪問
# node部署前端
為什么要引入nodejs?
1. 我覺得引入nodejs主要是為了分層開發,職責劃分,nodejs作為前端服務器,由前端開發人員負責,前端開發人員不需要知道java后臺是如何實現的,也不需要知道API接口是如何實現的,我們只需要關心我們前端的開發工作,并且管理好nodejs前端服務器,而后臺開發人員也不需要考慮如何前端是如何部署的,他只需要做好自己擅長的部分,提供好API接口就可以;
2. nodejs本身有著獨特的異步、非阻塞I/O的特點,這也就意味著他特別適合I/O密集型操作,在處理并發量比較大的請求上能力比較強,因此,利用它來充當前端服務器,向客戶端提供靜態文件以及響應客戶端的請求,我覺得這是一個很不錯的選擇。
前端服務器如何部署
nodejs前端服務器的職責
1、作為靜態文件服務器,當用戶訪問網站的時候,將index.html以及其引入的js、css、fonts以及圖片返回給用戶
2、負責將客戶端發來的ajax請求轉發給后臺服務器
其實前端服務器的部署工作是算比較簡單的,具體有以下兩個點:
1、將開發完的前端代碼,利用webpack打包成靜態壓縮文件
2、在服務器上,利用pm2負載均衡器來執行以下的代碼來開啟服務器:
# 部署到不同的站點
前端站點和后端API部署到不同的站點,就會產生跨域問題。
# 跨域處理
前端站點和后端API布署到不同的站點,就會產生跨域問題。
什么是同源策略?
同源是域名,協議,端口相同。也就是說如果不同,則是非同源。
同源策略是瀏覽器的一基本的安全功能,非同源訪問,瀏覽器會進行拒絕。
HMTL上面的SRC地址,你可以指定任何URL,表單提交,你可以提交到任何URL。
但是,你如果使用AJAX技術,就會受到同源策略的影響,拒絕提交。
現代瀏覽器幾乎都支持跨域資源請求的一種方式。這種技術叫CORS(跨域資源共享)
CORS 跨域分兩種:
1. 簡單跨域。
2. 復雜跨域。
解決方案:HTTP輸出標頭增加如何節點
注意有前端框架版本,對安全要求較高,不能使用通配符*,要指定跨域域名。
```
Access-Control-Allow-Origin:*
```
下面節點可填,可不填,根據實際情況,自行決定。
```
Access-Control-Allow-Methods:GET,POST,OPTIONS
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:根據請求頭的內容,填寫
```
注意:復雜跨域比要簡單跨域麻煩,更花費性能。因為復雜跨域在請求之前會先發一個options預請求,根據響應判斷服務器是否支持跨域。也就是說,實際上請求了兩次。
# Cookies作用域
不同的站點,如何通用Cookies?
一般情況只需把 cookies 作用域設置頂級域名,瀏覽器會自動把 cookies 在訪問子域名的時候捎上去。
示例,訪問二級域名時候,cookies 默認會被傳送過去。
~~~
頂級域名:baidul.com
cookies作用域:.baidu.com
二級域名:
www.baidu.com
api.baidu.com
~~~
# 其他
這個視你們項目的實際情況而定。我所了解的有兩種情況:
項目部署在云服務器上:前后端可以分開部署,各自的發布流程互不影響,可以通過一些手段(比如git的CI)實現自動化部署。但是前后端可能不在同一個域上,要做跨域處理。
項目要打成安裝包部署在指定的機器(一般是內網服務器)上:前后端代碼最終都要打在一個安裝包下面,所以主流的做法就是把前端生成的靜態資源包放到后端指定的靜態資源目錄,這一過程可能就是你現在的場景。這一過程能否實現自動化要看自己了,目前沒看到有類似的解決方案。這種方式有個好處就是前后端在同一個域下,不存在跨域的問題。
# 參考
[如何在開發時部署和運行前后端分離的JavaWeb項目](https://www.cnblogs.com/waliwaliwa/p/7222258.html)
- 講解 Markdown
- 示例
- SVN
- Git筆記
- github 相關
- DESIGNER'S GUIDE TO DPI
- JS 模塊化
- CommonJS、AMD、CMD、UMD、ES6
- AMD
- RequrieJS
- r.js
- 模塊化打包
- 學習Chrome DevTools
- chrome://inspect
- Chrome DevTools 之 Elements
- Chrome DevTools 之 Console
- Chrome DevTools 之 Sources
- Chrome DevTools 之 Network
- Chrome DevTools 之 Memory
- Chrome DevTools 之 Performance
- Chrome DevTools 之 Resources
- Chrome DevTools 之 Security
- Chrome DevTools 之 Audits
- 技巧
- Node.js
- 基礎知識
- package.json 詳解
- corepack
- npm
- yarn
- pnpm
- yalc
- 庫處理
- Babel
- 相關庫
- 轉譯基礎
- 插件
- AST
- Rollup
- 基礎
- 插件
- Webpack
- 詳解配置
- 實現 loader
- webpack 進階
- plugin 用法
- 輔助工具
- 解答疑惑
- 開發工具集合
- 花樣百出的打包工具
- 紛雜的構建系統
- monorepo
- 前端工作流
- 爬蟲
- 測試篇
- 綜合
- Jest
- playwright
- Puppeteer
- cypress
- webdriverIO
- TestCafe
- 其他
- 工程開發
- gulp篇
- Building With Gulp
- Sass篇
- PostCSS篇
- combo服務
- 編碼規范檢查
- 前端優化
- 優化策略
- 高性能HTML5
- 瀏覽器端性能
- 前后端分離篇
- 分離部署
- API 文檔框架
- 項目開發環境
- 基于 JWT 的 Token 認證
- 扯皮時間
- 持續集成及后續服務
- 靜態服務器搭建
- mock與調試
- browserslist
- Project Starter
- Docker
- 文檔網站生成
- ddd