一.前言
咕咕咕,許久不見 hhh,曉晨的 ASP.NET Core 奇淫技巧又開新篇章了,今天給大家帶來我在 ASP.NET Core 前后端分離開發中,在部署過程中的一些技巧。前后端分離的項目做過也有好幾個了,有簡單的,有復雜的。有一些簡單的項目部署可能會比較的簡便,下面給大家講講我所用過的部署方式。
二.Kestrel 全托法
此方法是將前端項目發布后,Copy 到后端 WebApi 項目下的 wwwroot 目錄下(沒有就新建),讓 Kestrel 來同時提供 api 和 前端靜態資源服務,適合內部使用小型項目,不建議用在中大型項目。
此方法的限制:前端必須使用基於 hash 的路由方式,基於 history 的不行;后端 WebApi 項目需要添加靜態文件中間件和默認文件中間件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles();
app.UseStaticFiles();
}
這樣進行發布后,即便是打包成 Docker 鏡像也只需要一個,比較方便。
此方法部署沒有跨域問題,后端無需配置跨域,沒有額外的 HTTP OPTIONS 請求。
三.Nginx 全代理法
此方法是 nginx 根據請求路徑來指向前端資源或者代理后端 api,和上面的方法一樣,也只使用一個域名,沒有跨域問題、
此方法的限制:后端必須設置給 api 設置統一的前綴。
api 的前綴,是自定義的,一般以 api
作為前綴,例如:/api/apple/add
。
安利一個快速為所有 api 設置前綴方法,通過在 MVC 框架啟動時給所有 api 增加一個 RouteAttribute 來實現。
定義一個類實現 IApplicationModelConvention
接口,遍歷所有 Controller 來為它們加上一個前綴路由
public class RouteConvention: IApplicationModelConvention
{
private readonly RouteAttribute _apiPrefix;
public XlRouteConvention(RouteAttribute apiPrefix)
{
_apiPrefix = apiPrefix;
}
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
// 已經標記了 RouteAttribute 的 Controller
var matchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel != null).ToList();
foreach (var selectorModel in matchedSelectors)
{
var attrPrefix =
new AttributeRouteModel(_apiPrefix);
selectorModel.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(attrPrefix, selectorModel.AttributeRouteModel);
}
// 沒有標記 RouteAttribute 的 Controller
var unmatchedSelectors = controller.Selectors.Where(x => x.AttributeRouteModel == null).ToList();
foreach (var selectorModel in unmatchedSelectors)
// 添加一個 路由前綴
selectorModel.AttributeRouteModel = new AttributeRouteModel(_apiPrefix);
}
}
}
使用:
services.AddControllers(op =>
{
op.Conventions.Insert(0, new RouteConvention(new RouteAttribute("api")));
})
這樣就會在所有的接口上都加一個指定的前綴,無需手動去給每個接口設置路由。
最后就是 nginx 的配置了:
location /api {
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;
proxy_pass http://localhost:5000;
}
location / {
root /opt/wwwroot;
try_files $uri $uri/ /index.html;
index index.html;
}
需要自行設置 root(前端資源根目錄) 和 proxy_pass(后端api地址) 的值
四.分開部署法
此方法顧名思義就是 后端API 和 前端程序分開部署,對於前后端沒有任何限制。
此方法的限制:需要給前端和后端分配單獨的域名,具有跨域問題需要配置跨域,因為有跨域,在調用API時還有會額外的 HTTP OPTIONS 請求。
五.結束
上面三種都是我使用的 SPA 程序部署方法,我個人比較喜歡的和經常使用的是Nginx全代理方法,如果有更好的方法歡迎大家和我討論。