Мы работаем над переносом нашего приложения на новую версию Angular. Старый (Angular.JS) был собственным приложением / репо, обслуживаемым приложением .NET Framework 4.5.2 ASP.NET MVC, которое перенаправляло каждый вызов на Home, которое возвращало Razor View, содержащее приложение angular, а затем запускало это вверх, возможно, перенаправив суффикс URL-адреса на фактическую страницу Angular. Например, он направит 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>
@JohnVelasquez Спасибо за ваш комментарий. Я сам бэкендер, вы имеете в виду Angular.JS RouterConfig? Если нет, то какая еще информация о маршрутизации приложения Angular 7 вам нужна? На данный момент я отредактировал основной пост, включив в него RouterConfig приложения Angular JS; пожалуйста, взгляните еще раз, если у вас есть время.
Вы используете ASP.NET MVC? Если да, включите RouteConfig
Извините, я забыл сказать вам, что я говорил об ASP.NET
Что ж, у него есть маршрут по умолчанию, который вы всегда получаете, и по умолчанию для этого маршрута следует перейти к Homecontroller, который возвращает представление, которое в сочетании с базовым макетом в razor запускает приложение Angular JS.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы вносили какие-либо изменения в свой файл Web.config? Вам нужно настроить его для базового приложения angular (используя модуль 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)
Привет! Я отредактировал свой пост, чтобы показать вам значения правил перезаписи IIS. Изначально моя виртуальная папка для Angular 7 называлась distv2, чтобы отразить, что dist был для Angular JS, а distv2 для Angular 7. Запросы, поступавшие для /v2/, затем переписывались в /distv2/. У меня были проблемы с этим, и поэтому я переименовал виртуальную папку v2, поэтому я считаю, что никакие другие перезаписи не нужны. Спасибо за уделенное время!
Web.Config IIS rewrite rulesRouteConfig измените это так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-адрес;
DefaultV2DefaultV2и в вашем HomeController обязательно добавьте IndexV2
HomeController
public ActionResult IndexV2()
{
return View();
}
Я понимаю, к чему вы идете, но это будет означать, что мое новое приложение Angular все еще необходимо интегрировать с ASP.NET MVC. Было бы круче, если бы их можно было разделить, чтобы мы могли при необходимости выпускать их по отдельности. Могу ли я не использовать localhost:4200/v2/test2/test_again/2323, используя правило перезаписи, которое перенаправляло бы этот URL-адрес на localhost:4200/v2, а затем позволяло angular делать все остальное (чего я и хочу)? Тогда я бы сделал почти то же самое, что и решение ASP.NET MVC.
Я думаю, что так лучше, чтобы вы могли разделить _Layout на каждую версию,
Это! Это ASP.NET MVC, а Angular JS обслуживается с использованием описываемой вами техники. Но приложение angular 7 - это просто статические файлы, поэтому, если они НЕ связаны с ASP.NET MVC, мы можем развернуть интерфейс и сервер отдельно. Вот почему я бы предпочел решение, в котором нам не нужно делать ничего специфичного для ASP.NET MVc :)
хммм, я не знаком с правилами перезаписи, это единственный ответ, который я могу для вас сделать
Причина, по которой он всегда будет возвращаться к 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, а затем позволяет angular маршрутизировать часть 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, никакой специальной угловой маршрутизации. Всего лишь эти простые шаги!
Для .Net Core 3 или выше
если 404 произошло в подкаталоге angular, это из-за конфигурации маршрута по умолчанию. так что это будет исправлено написанием этого кода при запуске.
app.Use(async (context, next) => {
await next();
if (context.Response.StatusCode == 404 &&
!System.IO.Path.HasExtension(context.Request.Path.Value) &&
!context.Request.Path.Value.ToLower().StartsWith("/api/")&&
!context.Request.Path.Value.ToLower().StartsWith("/swagger"))
{
context.Request.Path = "yousubdirectory/index.html";
await next();
}
});
app.UseMvcWithDefaultRoute();
включите сюда свой
RouterConfig