在请求管道的一个分支中提供SPA时,我的SPA文件给出404错误。如何使我的SPA可以使用我的静态文件?

时间:2018-08-07 15:33:22

标签: c# asp.net-core single-page-application

首先,在项目根目录中,有一个名为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 IApplicationBuilder实例上提供了温泉,那么它将起作用。

预先感谢您的帮助,这已经困扰了我几天了。

修改 我最终想要的设置如下。 /dashboard将服务SPA应用程序,访问该路由的任何人都必须经过身份验证。但是,诸如/Account/Login之类的路由将不属于SPA。

通过将UseSpa移到Map之外,Mvc或wwwroot中的静态文件未处理的任何路由都将呈现SPA,但是在访问例如/about我想显示一个404,而不是显示404的SPA。

2 个答案:

答案 0 :(得分:0)

对于app.Map,它将基于路径https://localhost:44378/dashboard/路由请求。这意味着只有带有https://localhost:44378/dashboard/的请求才会进入Spa中间件。

对于dashboard.UseSpa,它将监视https://localhost:44378/styles.bundle.csshttps://localhost:44378/dashboard/不匹配的spa静态文件。

如果您不想将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/");
                }
            });
        });    

答案 1 :(得分:0)

对,经过爱德华的澄清和帮助,我能够确定问题所在。正如爱德华指出的那样,由于对UseSpa的调用是在请求管道的分支内完成的,因此ClientApp/build处提供的静态资产不会使用,因为对这些资产的请求以{{1 }},而不是/static/。这意味着请求管道不知道它们。

我发现的修复实际上更多地在客户端构建上而不是服务器上,因为我无法正确地让服务器知道静态资产。该修复程序需要按here中所述设置/dashboard中的homepage属性。唯一的缺点是,这在运行package.json时不起作用,因为该构建实际上并未输出到文件系统,而是存储在Web服务器的内存中。

在服务器上,我确实必须将npm start移到app.UseSpaStaticFiles()调用中才能使其正常工作。

再次感谢爱德华帮助我更好地了解Map的工作原理。