C# 在请求管道的分支中为SPA提供服务时,我的SPA文件给出了404个错误。如何使我的SPA可以使用静态文件?
首先,在我的项目根目录中有一个名为C# 在请求管道的分支中为SPA提供服务时,我的SPA文件给出了404个错误。如何使我的SPA可以使用静态文件?,c#,asp.net-core,single-page-application,C#,Asp.net Core,Single Page Application,首先,在我的项目根目录中有一个名为ClientApp的文件夹,其中包含一个文件夹build,它是前端构建的输出所在 然后,在Startup.cs中,我在ConfigureServices中有以下内容: public void ConfigureServices(IServiceCollection services) { ... services.AddSpaStaticFiles(configuration => { configuration.Root
ClientApp
的文件夹,其中包含一个文件夹build
,它是前端构建的输出所在
然后,在Startup.cs
中,我在ConfigureServices
中有以下内容:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSpaStaticFiles(configuration => {
configuration.RootPath = "ClientApp/build";
});
}
下面,我的Configure
方法如下所示:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
} else {
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
app.Map("/dashboard", dashboard => {
dashboard.Use(async (context, next) => {
if (context.User.Identity.IsAuthenticated) {
await next();
return;
}
context.Response.Redirect("/Account/Login");
});
dashboard.UseSpa(spa => {
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment()) {
spa.UseProxyToSpaDevelopmentServer("http://localhost:3000");
}
});
});
}
如果我删除.Map(…)
并在app
iaapplicationbuilder实例中为spa提供服务,那么它就会工作
提前谢谢你的帮助,这已经困扰了我好几天了
编辑
我最终想要的设置如下/dashboard
将服务于SPA应用程序,任何访问该路由的人都必须经过身份验证。但是,诸如/Account/Login
之类的路由不属于SPA
通过将
UseSpa
移动到Map
之外,任何未由Mvc或wwwroot
中的静态文件处理的路由都将呈现SPA,但当访问例如/about
时,我想显示一个404,而不是呈现404的SPA。对于app.Map
,它将根据路径https://localhost:44378/dashboard/
。这意味着只有https://localhost:44378/dashboard/
将进入Spa
中间件
对于dashboard.UseSpa
,它将使用https://localhost:44378/styles.bundle.css
哪个将不匹配https://localhost:44378/dashboard/
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
app.Map("/dashboard", dashboard =>
{
dashboard.Use(async (context, next) =>
{
if (context.User.Identity.IsAuthenticated)
{
await next();
return;
}
context.Response.Redirect("/Account/Login");
});
});
如果您不想将SPA中的请求基本路径更改为https://localhost:44378/dashboard/
,您可以尝试将UseSpa
移动到app.Map(“/dashboard”
)之外
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
app.Map("/dashboard", dashboard =>
{
dashboard.Use(async (context, next) =>
{
if (context.User.Identity.IsAuthenticated)
{
await next();
return;
}
context.Response.Redirect("/Account/Login");
});
});
更新
要更改SPA静态文件请求URL,您可以尝试更改package.json
,如下所示:
"start": "ng serve --base-href=/dashboard/ --serve-path=/ --live-reload-client=https://localhost:port/frontend/sockjs-node/",
开发过程中的另一个选项是在Startup
app.Map("/dashboard", frontendApp =>
{
frontendApp.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start -- --base-href=/frontend/ --serve-path=/ --live-reload-client=https://localhost:44302/frontend/sockjs-node/");
}
});
});
没错,在Edward进行了一些澄清和帮助之后,我发现了这个问题。正如Edward指出的,由于对
UseSpa
的调用是在请求管道的一个分支内完成的,所以在ClientApp/build
上服务的静态资产不会被使用,因为这些资产的请求以/static/而不是/dashboard
。这意味着请求管道不知道它们
我发现的修复实际上更多的是在客户端构建上,而不是在服务器上,因为我无法正确地让服务器知道静态资产。修复需要在package.json
中设置homepage
属性。唯一的缺点是,在运行npm start
sinc时,这不起作用e构建实际上不是输出到文件系统,而是在web服务器的内存中
在服务器上,我确实必须将app.UseSpaStaticFiles()
移动到Map
调用中,才能使其正常工作
再次感谢Edward帮助我更好地理解Map
的工作原理。将UseSpa
移动到app之外。Map
将使SPA可用于除任何MVC路由之外的所有路径。但这不是我想要的,因为“默认”响应不应该是面向客户端的应用程序(即使显示404)在我看来。但是,您的解释确实澄清了SpaServices如何运行的一些问题,因此感谢您。对于angular文件的身份验证和授权,如何使用?spa
中的哪些敏感信息?一般来说,静态文件是公共访问。它与访问静态文件无关。我的意思是,如果我把UseSpa
从Map
中拿出来,然后在Mvc系统不处理的任何路线上都可以访问spa。因此/dashboard
会去spa,但是/about
也会去,即使我的站点中不存在该页面。我会编辑帖子以澄清我的想法。是的,这会有工作正常,但我的SPA是使用create react app的react应用程序,而不是使用Angular cli的Angular应用程序。为了使Angular服务器和实时重新加载在开发中正常工作,请包括app.useSpa(s=>s.Options.SourcePath=null;if(env.IsDevelopment())s.UseProxyToSpaDevelopmentServer(“http://localhost:4200)