一.前言
咕咕咕,许久不见 hhh,晓晨的 ASP.NET Core 奇淫技巧又开新篇章了,今天给大家带来我在 ASP.NET Core 前后端分离开发中,在部署过程中的一些技巧。前后端分离的项目做过也有好几个了,有简单的,有复杂的。有一些简单的项目部署可能会比较的简便,下面给大家讲讲我所用过的部署方式。
二.Kestrel 全托法
此方法是将前端项目发布后,Copy 到后端 WebApi 项目下的 wwwroot 目录下(没有就新建),让 Kestrel 来同时提供 api 和 前端静态资源服务,适合内部使用小型项目,不建议用在中大型项目。
此方法的限制:前端必须使用基于 hash 的路由方式,基于 history 的不行;后端 WebApi 项目需要添加静态文件中间件和默认文件中间件
代码语言:javascript复制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);
}
}
}
使用:
代码语言:javascript复制services.AddControllers(op =>
{
op.Conventions.Insert(0, new RouteConvention(new RouteAttribute("api")));
})
这样就会在所有的接口上都加一个指定的前缀,无需手动去给每个接口设置路由。
最后就是 nginx 的配置了:
代码语言:javascript复制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全代理方法,如果有更好的方法欢迎大家和我讨论。