带有反应模板的 Asp.net 核心 Web 应用程序:在开发中,服务器首先检查 mvc 路由,但在生产中服务器仅返回 index.html

Posted

技术标签:

【中文标题】带有反应模板的 Asp.net 核心 Web 应用程序:在开发中,服务器首先检查 mvc 路由,但在生产中服务器仅返回 index.html【英文标题】:Asp.net core web application with react template: in development, server checks mvc routes first, but in prodcution the server only returns index.html 【发布时间】:2021-01-04 12:45:44 【问题描述】:

我正在尝试将使用剃须刀页面的现有 MVC 应用程序迁移到 Web API + ReactJS 客户端。我正在逐步执行此操作,这意味着我已经迁移了主页(主页/索引)以及一些其他页面/功能来做出反应。 razor 页面和那些在 react 中实现的页面之间存在链接。这在运行反应开发服务器的开发环境中完美运行。

例如在开发环境中,如果我路由到 localhost:12345/Controller/Action(对于可用的控制器和操作)服务器执行相应的操作并返回正确的视图,如果我尝试访问未知的路由server 它返回 index.html 并且 react-router 从这一点开始处理路由。这是公认的行为,在开发环境中就像一种魅力。

但是当我构建 react 应用程序并在生产模式下运行应用程序时,情况发生了变化。请求永远不会到达服务器,并由 react-router 在客户端处理。当我硬刷新页面时,它会触发已接受的 MVC 操作。

我希望在生产开发中具有相同的行为。

这就是 starup.cs 文件的样子。

        // ConfigureServices
        .
        .
        .
        // In production, the React files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        
            configuration.RootPath = "ReactSource/build";
        );
        .
        .
        .


       
        // Configure
        .
        .
        .
        app.UseStaticFiles();
        app.UseSpaStaticFiles();
        app.UseMvc(routes =>
        
            routes.MapRoute(
                name: "default",
                template: "controller/action");
        );


        app.UseSpa(spa =>
        
            spa.Options.SourcePath = "ReactSource";

            // do not start the react development server in production
            if (env.IsDevelopment())  spa.UseReactDevelopmentServer(npmScript: "start"); 
        );
        .
        .

知道我在这里缺少什么吗?我应该为此修改 react-router 吗?

【问题讨论】:

When I hard-refresh the page it triggers the MVC actions as accepted though. hard-refresh 是什么意思,使用 Ctrl + F5 ?硬刷新后,代码是否运行良好?您能否发布有关 react-router 的相关代码以重现问题?另外,在MVC模板中,尝试设置默认的控制器和动作,比如template: "controller=Home/action=Index"); 【参考方案1】:

要拥有一个Progress Web 应用程序,您必须在您的 React Web 应用程序中启用 Service Worker。

为了解决生产模式下的缓存问题,您必须在index.tsx文件中输入以下代码:

ReactDOM.render(
    <BrowserRouter basename=baseUrl>
        <App />
    </BrowserRouter>,
    rootElement);

//index page is Route exact path.
if (window.location.href.includes('index'))
    registerServiceWorker();
else
    unregisterAndReload();

function unregisterAndReload() 
    navigator.serviceWorker.ready.then(registration => 
        registration.unregister().then(() => 
            window.location.reload();
        );
    );

App.tsx 文件应如下所示:

render() 
        return (
            <Layout>
                <Route exact path='/index' component=Home />
                <Route path='/contact' component=ContactUs />
            </Layout>
        );
    

【讨论】:

【参考方案2】:

我通过关闭(取消注册)开箱即用的 create-react-app 服务工作者解决了我的问题,该服务工作者试图缓存资产并阻止请求到达服务器。

在 index.js 文件中,我只是简单地导入了 unregister from "./registerServiceWorker" 并将自动生成的 index.js 文件末尾的 registerServiceWorker(); 替换为 unregister();

【讨论】:

以上是关于带有反应模板的 Asp.net 核心 Web 应用程序:在开发中,服务器首先检查 mvc 路由,但在生产中服务器仅返回 index.html的主要内容,如果未能解决你的问题,请参考以下文章

在 NET 5 asp.net 核心 Web 应用程序中为 Kestrel 启用 Windows 身份验证

带有 EF Core 更新实体的 ASP.Net 核心 Web Api 如何

带有反应应用程序的 POST 上的 ASP.NET CORS 异常

ASP.NET Web API 登录方法

如何在asp.net核心中从客户端调用web api方法?

通过 Internet 公开我的 asp.net 核心 Web 应用程序