咕咕咕,許久不見 hhh,曉晨的 ASP.NET Core 奇淫技巧又開新篇章了,今天給你們帶來我在 ASP.NET Core 先後端分離開發中,在部署過程當中的一些技巧。先後端分離的項目作過也有好幾個了,有簡單的,有複雜的。有一些簡單的項目部署可能會比較的簡便,下面給你們講講我所用過的部署方式。html
此方法是將前端項目發佈後,Copy 到後端 WebApi 項目下的 wwwroot 目錄下(沒有就新建),讓 Kestrel 來同時提供 api 和 前端靜態資源服務,適合內部使用小型項目,不建議用在中大型項目。前端
此方法的限制:前端必須使用基於 hash 的路由方式,基於 history 的不行;後端 WebApi 項目須要添加靜態文件中間件和默認文件中間件nginx
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseDefaultFiles(); app.UseStaticFiles(); }
這樣進行發佈後,即使是打包成 Docker 鏡像也只須要一個,比較方便。後端
此方法部署沒有跨域問題,後端無需配置跨域,沒有額外的 HTTP OPTIONS 請求。api
此方法是 nginx 根據請求路徑來指向前端資源或者代理後端 api,和上面的方法同樣,也只使用一個域名,沒有跨域問題、跨域
此方法的限制:後端必須設置給 api 設置統一的前綴。app
api 的前綴,是自定義的,通常以 api
做爲前綴,例如:/api/apple/add
。框架
安利一個快速爲全部 api 設置前綴方法,經過在 MVC 框架啓動時給全部 api 增長一個 RouteAttribute 來實現。前後端分離
定義一個類實現 IApplicationModelConvention
接口,遍歷全部 Controller 來爲它們加上一個前綴路由ui
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全代理方法,若是有更好的方法歡迎你們和我討論。