带有反应模板的 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的主要内容,如果未能解决你的问题,请参考以下文章