ASP.NET Core 奇淫技巧之SPA部署


一.前言

咕咕咕,許久不見 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全代理方法,如果有更好的方法歡迎大家和我討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM