Asp.net 带有 React 模板的核心 Web 应用程序:在开发中,服务器首先检查 mvc 路由,但在生产中仅检查服务器 returns 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
我正在尝试将使用 razor 页面的现有 MVC 应用程序迁移到 Web API + ReactJS 客户端。我正在逐步执行此操作,这意味着我已经迁移了主页 (Home/Index) 以及其他一些 pages/features 以做出反应。 razor 页面和在 react 中实现的页面之间存在链接。这在 运行s 反应开发服务器的开发环境中完美运行。
例如在开发环境中,如果我路由到 localhost:12345/Controller/Action(对于可用的控制器和操作)服务器执行相应的操作和 returns 正确的视图,如果我尝试访问一条服务器未知的路由 returns 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 吗?
我通过关闭(注销)开箱即用的服务工作者解决了我的问题,它试图缓存资产并阻止请求到达服务器。
在 index.js 文件中,我只是导入了 { unregister } from "./registerServiceWorker"
并在自动生成的 index.js 文件末尾用 unregister();
替换了 registerServiceWorker();
。
要拥有一个 Progress Web 应用程序,您必须在您的 React 网络应用程序中启用 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>
);
}
我正在尝试将使用 razor 页面的现有 MVC 应用程序迁移到 Web API + ReactJS 客户端。我正在逐步执行此操作,这意味着我已经迁移了主页 (Home/Index) 以及其他一些 pages/features 以做出反应。 razor 页面和在 react 中实现的页面之间存在链接。这在 运行s 反应开发服务器的开发环境中完美运行。
例如在开发环境中,如果我路由到 localhost:12345/Controller/Action(对于可用的控制器和操作)服务器执行相应的操作和 returns 正确的视图,如果我尝试访问一条服务器未知的路由 returns 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 吗?
我通过关闭(注销)开箱即用的服务工作者解决了我的问题,它试图缓存资产并阻止请求到达服务器。
在 index.js 文件中,我只是导入了 { unregister } from "./registerServiceWorker"
并在自动生成的 index.js 文件末尾用 unregister();
替换了 registerServiceWorker();
。
要拥有一个 Progress Web 应用程序,您必须在您的 React 网络应用程序中启用 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>
);
}