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

一.前言

咕咕咕,許久不見 hhh,曉晨的 ASP.NET Core 奇淫技巧又開新篇章了,今天給你們帶來我在 ASP.NET Core 先後端分離開發中,在部署過程當中的一些技巧。先後端分離的項目作過也有好幾個了,有簡單的,有複雜的。有一些簡單的項目部署可能會比較的簡便,下面給你們講講我所用過的部署方式。html

二.Kestrel 全託法

此方法是將前端項目發佈後,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 全代理法

此方法是 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全代理方法,若是有更好的方法歡迎你們和我討論。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息