华域联盟 .Net ASP.NET Core 集成 React SPA应用的步骤

ASP.NET Core 集成 React SPA应用的步骤

ASP.NET Core 集成 React SPA应用的步骤
 更新时间:2021年04月28日 09:52:09   作者:Agile.Zhou  

这篇文章主要介绍了ASP.NET Core 集成 React SPA应用的步骤,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下

目录wwwroot\\uiReactUIMiddleware运行一下总结
AgileConfig的UI使用react重写快完成了。上次搞定了基于jwt的登录模式(AntDesign Pro + .NET Core 实现基于JWT的登录认证),但是还有点问题。现在使用react重写后,agileconfig成了个确确实实的前后端分离项目。那么其实部署的话要分2个站点部署,把前端build完的静态内容部署在一个网站,把server端也部署在一个站点。然后修改前端的baseURL让spa的api请求都指向server的网站。
这样做也不是不行,但是这不符合AgileConfig的精神,那就是简单。asp.net core程序本身其实就是一个http服务器,所以完全可以把spa网站使用它来承载。这样只需要部署一个站点就可以同时跑spa跟后端server了。
其实最简单的办法就是把build完的文件全部丢wwwroot文件夹下面。然后访问:

localhost:5000/index.html

但是这样我们的入口是index.html,这样看起来比较别扭,不够友好。而且这些文件直接丢在wwwroot的根目录下,会跟网站其他js、css等内容混合在一起,也很混乱。
那么下面我们就要解决这两个文件,我们要达到的目的有2个:

spa的入口path友好,比如localhost:5000/ui
spa静态文件存放的目录独立,比如存放在wwwroot/ui文件夹下,或者别的什么目录下。

要实现以上内容只需要一个自定义中间件就可以了。
wwwroot\\ui

wwwroot\\ui

我们把build完的静态文件全部复制到wwwroot\\ui文件夹内,以跟其他静态资源进行区分。当然你也可以放在任意目录下,只要是能读取到就可以。
ReactUIMiddleware

namespace AgileConfig.Server.Apisite.UIExtension
{
public class ReactUIMiddleware
{
private static Dictionary<string, string> _contentTypes = new Dictionary<string, string>
{
{".html", "text/html; charset=utf-8"},
{".css", "text/css; charset=utf-8"},
{".js", "application/javascript"},
{".png", "image/png"},
{".svg", "image/svg+xml"},
{ ".json","application/json;charset=utf-8"},
{ ".ico","image/x-icon"}
};
private static ConcurrentDictionary<string, byte[]> _staticFilesCache = new ConcurrentDictionary<string, byte[]>();
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public ReactUIMiddleware(
RequestDelegate next,
ILoggerFactory loggerFactory
)
{
_next = next;
_logger = loggerFactory.
CreateLogger<ReactUIMiddleware>();
}

private bool ShouldHandleUIRequest(HttpContext context)
{
return context.Request.Path.HasValue && context.Request.Path.Value.Equals("/ui", StringComparison.OrdinalIgnoreCase);
}

private bool ShouldHandleUIStaticFilesRequest(HttpContext context)
{
//请求的的Referer为 0.0.0.0/ui ,以此为依据判断是否是reactui需要的静态文件
if (context.Request.Path.HasValue && context.Request.Path.Value.Contains("."))
{
context.Request.Headers.TryGetValue("Referer", out StringValues refererValues);
if (refererValues.Any())
{
var refererValue = refererValues.First();
if (refererValue.EndsWith("/ui", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
}

return false;
}

public async Task Invoke(HttpContext context)
{
const string uiDirectory = "wwwroot/ui";
//handle /ui request
var filePath = "";
if (ShouldHandleUIRequest(context))
{
filePath = uiDirectory + "/index.html";
}
//handle static files that Referer = xxx/ui
if (ShouldHandleUIStaticFilesRequest(context))
{
filePath = uiDirectory + context.Request.Path;
}

if (string.IsNullOrEmpty(filePath))
{
await _next(context);
}
else
{
//output the file bytes

if (!File.Exists(filePath))
{
context.Response.StatusCode = 404;
return;
}

context.Response.OnStarting(() =>
{
var extType = Path.GetExtension(filePath);
if (_contentTypes.TryGetValue(extType, out string contentType))
{
context.Response.ContentType = contentType;
}
return Task.CompletedTask;
});

await context.Response.StartAsync();

byte[] fileData = null;
if (_staticFilesCache.TryGetValue(filePath, out byte[] outfileData))
{
fileData = outfileData;
}
else
{
fileData = await File.ReadAllBytesAsync(filePath);
_staticFilesCache.TryAdd(filePath, fileData);
}
await context.Response.BodyWriter.WriteAsync(fileData);

return;
}
}
}
}

大概解释下这个中间件的思路。这个中间件的逻辑大概是分量部分。
1.拦截请求的路径为/ui的请求,直接从ui文件夹读取index.html静态文件的内容然后输出出去,这就相当于直接访问/index.html。但是这样的路径形式看起来更加友好。
2.拦截react spa需要的静态资源文件,比如css文件,js文件等。这里比较麻烦,因为spa拉静态文件的时候path是直接从网站root开始的,比如localhost:5000/xxx.js,那么怎么区分出来这个文件是react spa需要的呢?我们判断一下请求的Referer头部,如果Referer的path是/ui,那么就说明是react spa需要的静态资源,同样从ui文件夹去读取。
这里还需要给每个response设置指定的contentType不然浏览器无法准确识别资源。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseMiddleware<ExceptionHandlerMiddleware>();
}
app.UseMiddleware<ReactUIMiddleware>();

...
...

}

在Startup类的Configure方法内使用这个中间件。这样我们的改造就差不多了。
运行一下

访问下localhost:5000/ui 可以看到spa成功加载进来了。
总结

为了能让asp.net core承载react spa应用,我们使用一个中间件进行拦截。当访问对应path的时候从本地文件夹内读取静态资源返回给浏览器,从而完成spa所需要资源的加载。这次使用react spa来演示,其实换成任何spa应用都是一样的操作。
代码在这:ReactUIMiddleware
以上就是ASP.NET Core 集成 React SPA应用的步骤的详细内容,更多关于ASP.NET Core 集成 React SPA的资料请关注华域联盟其它相关文章!

您可能感兴趣的文章:如何在Asp.Net Core中集成ABP Dapper如何在Asp.Net Core中集成Refitasp.net core集成CKEditor实现图片上传功能的示例代码asp.net core 使用 TestServer 来做集成测试的方法在ASP.NET Core Mvc集成MarkDown的方法asp.net core集成JWT的步骤记录Asp.Net Core利用xUnit进行主机级别的网络集成测试详解asp.net core集成MongoDB的完整步骤ASP.NET Core与NLog集成的完整步骤ASP.NET Core+Docker+Jenkins实现持续集成的完整实例asp.net core 2.0 webapi集成signalr(实例讲解)asp.net core集成kindeditor实现图片上传功能

ASP.NET
Core
React
SPA

相关文章
ASP.NET中application对象的使用介绍这篇文章主要介绍了ASP.NET中application对象的使用,需要的朋友可以参考下 2014-04-04
Visual Studio 2017 RC 初探安装教程这篇文章主要为大家详细介绍了Visual Studio 2017 RC初探安装教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 2017-03-03
Asp.net MVC SignalR来做实时Web聊天实例代码本篇文章主要介绍了Asp.net SignalR来做实时Web聊天实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2017-06-06
详解ASP.NET Core端点路由的作用原理这篇文章主要介绍了详解ASP.NET Core端点路由的作用原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 2020-07-07
验证用户必选CheckBox控件与自定义验证javascript代码CheckBox控件,由于它的值是选择与非选择。因此在提交数据时,想让用户必须选择CheckBox,普通情况之下,不好做验证;但我们可以使用asp:CustomValidator来验证,不过还得写自定义验证Javascript代码 2013-01-01
详解如何在ASP.NET Core中使用Route特性这篇文章主要介绍了如何在ASP.NET Core中使用Route特性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 2021-01-01
ASP.NET服务器端控件RadioButtonList,DropDownList,CheckBoxLi这三个控件都有一个Items集合,可以用 RepeatLayout 和 RepeatDirection 属性来控制列表的呈现形式 2013-10-10
详解在.net中读写config文件的各种方法本篇文章主要介绍了在.net中读写config文件的各种方法,详细的介绍各种配置文件的读写操作,具有一定的参考价值,有兴趣的可以了解一下。
2016-12-12
.NET中函数Main的使用技巧任何语言开发出来的程序,都会有一个程序入口函数,可能每个语言所使用的程序入口函数名称不一样,但是它们的作用都是一样的,都是被操作系统去调用。那么本文主要总结.NET中的程序入口函数Main使用的小技巧。 2016-10-10
ASP.NET文件上传控件Uploadify的使用方法这篇文章主要为大家详细介绍了ASP.NET文件上传控件Uploadify的使用方法,感兴趣的小伙伴们可以参考一下 2016-03-03

最新评论

本文由 华域联盟 原创撰写:华域联盟 » ASP.NET Core 集成 React SPA应用的步骤

转载请保留出处和原文链接:https://www.cnhackhy.com/4921.htm

本文来自网络,不代表华域联盟立场,转载请注明出处。

作者:

上一篇

已经没有了

发表回复

联系我们

联系我们

2551209778

在线咨询: QQ交谈

邮箱: [email protected]

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部