Маршрутизация в Angular 7 работает в подпапке не работает правильно - PullRequest
0 голосов
/ 11 января 2019

Мы работаем над переносом нашего приложения на новую версию Angular. Старый (Angular.JS) был его собственным приложением / репо, обслуживаемым приложением ASP.NET MVC .NET Framework 4.5.2, которое перенаправляло бы каждый вызов на Home, которое возвращало бы Razor View, содержащее угловое приложение и затем запустите его, возможно, перенаправив суффикс URL на реальную угловую страницу. Например, он будет направлять www.website.com/profile к маршруту profile в Angular, НЕ пытаясь получить доступ к папке с именем profile на сервере. Интеграция нашего API и приложения Angular.JS не слишком приятна, но работает. На сервере также есть виртуальные папки в IIS для других подпапок, к которым следует обращаться, таких как шрифты, изображения, конфигурации и т. Д.

В настоящее время я работаю над тем, чтобы приложение Angular 7 работало вместе с приложением Angular.JS. Мы хотим запустить приложение Angular 7 для запуска внутри каталога текущего приложения, а затем перенести его в свое собственное веб-приложение, потому что наше новое приложение Angular представляет собой просто набор статических файлов и его не нужно связывать с сервером. больше. По сути, нет необходимости в какой-либо конфигурации ASP.NET MVC.

Текущий URL будет www.website.com и вернет приложение Angular.JS. Новый будет www.website.com/v2/ и вернет приложение Angular 7. Если мы завершили версию v2 страницы profile, переход к wwww.website.com/v2/profile теперь должен перейти к странице profile приложения Angular 7.

В IIS одной из виртуальных папок является папка с именем dist, которая ведет к расположению файлов приложения Angular.JS. Теперь настроен новый файл под названием v2, который приводит к расположению файлов приложения Angular 7. Другой, называемый assets, ведет к папке assets приложения Angular 7.

Теперь, когда я перехожу на www.website.com/v2/, Angular запускается и направляет меня к www.website.com/v2/home, который является домашним маршрутом.

Проблема в том, что когда я сам набираю www.website.com/v2/home, это приводит к тому, что приложение возвращается к www.website.com. и, таким образом, он снова загружает приложение Angular.JS. Здесь нет ошибок или перенаправлений. Кажется, что он просто игнорирует часть, которая идет после части v2/, хотя Angular.JS делает это просто отлично.

TL; DR Переход к www.website.com/v2 загружает Angular 7, но переход к v2/{{Anything}} приводит к тому, что приложение возвращается к приложению Angular.JS, работающему на www.website.com, даже если {{anything}} была внутренней ссылкой в ​​Angular 7, она будет перемещаться по маршруту {{anything}}.

Я строю проект Angular с помощью следующей команды:

ng build --configuration=dev --deploy-url=/v2/ --base-href=/v2/

Маршруты в приложении angular 7 выглядят так:

const routes: Routes = [
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full',
  },
  {
    path: '',
    canActivate: [AuthGuard],
    component: DefaultLayoutComponent,
    children: [
      {
        path: 'home',
        component: DashboardComponent,
        canLoad: [NoAuthGuard],
      },
      {
        path: 'contact',
        loadChildren: './modules/contact/contact.module#ContactModule',
        canLoad: [NoAuthGuard],
      },
      {
        path: 'timesheets',
        loadChildren: './modules/timesheet/timesheet.module#TimesheetModule',
        canLoad: [NoAuthGuard],
      },
      {
        path: 'users',
        loadChildren: './modules/users/users.module#UsersModule',
        canLoad: [NoAuthGuard, NgxPermissionsGuard],
        data: {
          permissions: {
            only: 'seeUsersPage',
            redirectTo: '/403',
          },
        },
      },
      {
        path: 'profile',
        loadChildren: './modules/profile/profile.module#ProfileModule',
        canLoad: [NoAuthGuard],
      },
    ],
  },
  {
    path: 'login',
    component: LoginComponent,
  },
  {
    path: '403',
    component: Page403Component,
  },
  {
    path: '**',
    redirectTo: '/home',
    pathMatch: 'full',
  },
];

Может кто-нибудь сказать мне, как я могу заставить, например, набрать www.website.com/v2/contact в браузере, чтобы перейти на страницу контактов v2, при этом делая возможной внутреннюю навигацию (так что если пользователь нажимает на «перейти на страницу контактов v2» «внутри приложения Angular 7 оно также переходит на страницу контактов v2)

Редактировать: Запрошена информация об Angular.JS Routerconfig и серверной части web.config; Я предоставил их ниже.

RouterConfig:

$routeProvider
    .when('/', {
      templateUrl: 'scripts/home/home.html',
      controller: 'HomeController',
      controllerAs: 'homeCtrl'
    })
    .when('/gebruikers', {
      templateUrl: 'scripts/users/users.html',
      controller: 'UsersController',
      controllerAs: 'usersCtrl'
    })
    .when('/profiel', {
      templateUrl: 'scripts/profile/profile.html',
      controller: 'ProfileController',
      controllerAs: 'profileCtrl'
    })
    .when('/timesheets', {
      templateUrl: 'scripts/timesheets/timesheets.html',
      controller: 'TimesheetsController',
      controllerAs: 'timesheetsCtrl',
      reloadOnSearch: false
    })
    .when('/facturen', {
      templateUrl: 'scripts/invoices/invoices.html',
      controller: 'InvoicesController',
      controllerAs: 'invoicesCtrl',
      reloadOnSearch: false
    })
    .when('/opdrachten', {
      templateUrl: 'scripts/vacancies/vacancies.html',
      controller: 'VacanciesController',
      controllerAs: 'vacanciesCtrl'
    })
    .when('/contact', {
      templateUrl: 'scripts/contact/contact.html',
      controller: 'ContactController',
      controllerAs: 'contactCtrl'
    })
    .when('/help', {
      templateUrl: 'scripts/help/help.html',
      controller: 'HelpController',
      controllerAs: 'helpCtrl'
    })
    .otherwise({
      redirectTo: '/'
    });

Web.Config IIS rewrite rules:

 <rewrite>
      <rules>
        <clear />
        <rule name="Redirect Angular endpoints to MVC Home" enabled="true">
          <match url="^(profiel|timesheets|facturen|opdrachten|contact|help|gebruikers)" negate="false" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
          <action type="Rewrite" url="Home" logRewrittenUrl="false" />
        </rule>
     <!-- Some other rules that are not important are here, they redirect HTTP to HTTPS -->
     </rules>
  </rewrite>

Ответы [ 3 ]

0 голосов
/ 12 января 2019
  1. Удалите Web.Config IIS rewrite rules
  2. В вашем RouteConfig измените его таким образом

RouteConfig

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // don't change the arrangement, this must be executed first
        routes.MapRoute(
                name: "V2",
                url: "v2/{*url}",
                defaults: new { controller = "Home", action = "IndexV2", id = UrlParameter.Optional }
            );

        routes.MapRoute(
                name: "Default",
                url: "{*url}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
 }

По сути, он будет перехватывать все ваши маршруты, указанные с определенным именем маршрута, {*url} перехватывает весь сегмент маршрута независимо от значения.

Итак, когда мы говорим, что URL есть;

  • localhost: 4200 / test <- это указывает на <code>Default
  • localhost: 4200 / v2 / test <- это указывает на <code>V2
  • localhost: 4200 / test / что-то / 2323 <- это указывает на <code>Default
  • localhost: 4200 / v2 / test2 / test_again / 2323 <- это указывает на <code>V2

и в вашем HomeController обязательно добавьте IndexV2

HomeController

public ActionResult IndexV2()
{
    return View();
} 
0 голосов
/ 17 января 2019

Причина, по которой он всегда будет перенаправляться на URL v1, заключается в том, что приложение angular 7 содержало файл web.config, который выглядел так:

<configuration>
    <system.webServer>
      <rewrite>
        <rules>
          <rule name="Angular" stopProcessing="true">
            <match url=".*" />
            <conditions logicalGrouping="MatchAll">
              <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
              <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            </conditions>
            <action type="Rewrite" url="/" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
</configuration>

Я считаю, что это развертывание IIS по умолчанию, и член команды мог бы добавить это. Я никогда не думал о наличии web.config во внешнем проекте.

По сути, это правило заботится о перенаправлении пользователя в index.html. Например, www.website.com/folder обычно приводит пользователя к папке с именем folder на веб-сервере, но это не то место, где работает Angular и может вызвать 404. Это правило возвращает пользователя к www.website.com, а затем позволяет угловой маршрутизации folder часть.

Поскольку я запускаю свое приложение в подпапке, я изменил url="/" на url="/v2/", и он сразу заработал!

Не забудьте построить проект с ng build --configuration=dev --deploy-url=/v2/ --base-href=/v2/! URL-адрес для развертывания необходим, поскольку файлы scripts / css / other не найдены в корневой папке сервера; находится в / v2 /. Base-href необходим для маршрутизатора; он должен начать маршрутизацию приложения с www.website.com/v2/, а не с www.website.com/!

Никаких других правил перезаписи iis не требуется, никаких настроек asp.net, никакой специальной угловой маршрутизации. Просто эти простые шаги!

0 голосов
/ 11 января 2019

Вносили ли вы какие-либо изменения в файл Web.config? Вам нужно настроить его для базового углового приложения (используя модуль UrlRewrite). Я полагаю, что для вашего случая использования может потребоваться модификация ...

<rewrite>
    <rules>
      <rule name="Angular RoutesV1" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/my/app/" />
      </rule>
    </rules>
  </rewrite>

Я предполагаю, что вам нужно добавить еще одно «правило» здесь. Надеюсь это поможет!!! (примечание: предполагается, что перезапись соответствует вашему значению href базовой сборки ng)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...