Asp.net основное веб-приложение с шаблоном react: при разработке сервер сначала проверяет маршруты mvc, но при производстве сервер возвращает только index.html

#reactjs #react-router #asp.net-core-mvc #asp.net-mvc-routing #create-react-app

#reactjs #react-router #asp.net-core-mvc #asp.net-mvc-routing #create-react-app

Вопрос:

Я пытаюсь перенести существующее приложение MVC, которое использует страницы razor, в web API клиент ReactJS. Я делаю это шаг за шагом, что означает, что я перенес домашнюю страницу (Home / Index) плюс несколько других страниц / функций в react. Существуют ссылки между страницами razor и теми, которые реализованы в react. Это отлично работает в среде разработки, в которой работает сервер разработки react.

Например, в среде разработки, если я направляюсь на localhost:12345/Controller/ Action (для доступного контроллера и действия), сервер выполняет соответствующее действие и возвращает правильное представление, и если я пытаюсь получить доступ к маршруту, который неизвестен серверу, он возвращает index.html и react-router обрабатывает маршрутизацию из этоготочка. Это общепринятое поведение и работает как шарм в среде разработки.

Но все меняется, когда я создаю приложение react и запускаю приложение в рабочем режиме. Запрос никогда не доходит до сервера и обрабатывается на стороне клиента с помощью react-router. Когда я жестко обновляю страницу, она запускает действия MVC, как принято.

Я хотел бы иметь такое же поведение, которое он имеет при разработке для производства.

Вот как выглядит файл автозагрузки.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 для этого?

Комментарии:

1. 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:

Я решил свою проблему, отключив (отменив регистрацию) готового сервисного работника create-react-app, который пытался кэшировать ресурсы и предотвращал попадание запросов на сервер.

В index.js файл, я просто импортировал { unregister } from "./registerServiceWorker" и registerServiceWorker(); заменил unregister(); на в конце автоматически сгенерированного index.js досье.

Ответ №2:

Чтобы иметь веб-приложение Progress, вы должны включить Service worker в своем веб-приложении React.

Для решения проблемы с кэшем в рабочем режиме вы должны ввести следующий код в файл 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>
        );
    }