咕咕咕,许久不见 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全代理方法,若是有更好的方法欢迎你们和我讨论。