带有反应模板的 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 如何