Угловая маршрутизация веб-приложений в Juniper SSL VPN
В настоящее время я работаю над простым веб-приложением, использующим AngularJS. В процессе разработки я тестировал его, пока приложение обслуживалось IIS локально. Однако, когда я развернул его на веб-сервере компании и запустил его в рамках Juniper SSL VPN, начались проблемы.
Сначала мне пришлось применить следующее "исправление": ошибка маршрутизации AngularJS при работе в Juniper SSL VPN #8905
Но вышеприведенное исправление только решило часть проблемы. Проблема, которая остается, заключается в том, что AngularJS возвращает следующую ошибку, когда я пытаюсь загрузить представление, отличное от стандартного ('/') представления ($location.path('/anotherView')) из контроллера представления, я получаю следующее сообщение об ошибке:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
http://errors.angularjs.org/1.3.15/$rootScope/infdig?p0=10&p1=%5B%5D
at REGEX_STRING_REGEXP (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:63)
at Scope.$get.Scope.$digest (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:14340)
at Scope.$get.Scope.$apply (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:14565)
at done (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9685)
at completeRequest (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9875)
at XMLHttpRequest.requestLoaded (,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9816)(anonymous function) @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:11649$get @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:8583$get.Scope.$apply @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:14567done @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9685completeRequest @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9875requestLoaded @ ,DanaInfo=server1.mydomain.nl,CT=js+angular.js:9816
Я проверил его с помощью стандартной маршрутизации AngularJS и механизма Angular ui.router, и оба дали одинаковый результат.
Любая помощь в решении этой проблемы действительно ценится!
3 ответа
Проблема решается путем настройки Juniper в качестве обратного прокси.
В моем случае у меня были проблемы с переписыванием URL. Шлюз справился со стандартными атрибутами href в HTML, но не для вызовов Angular AJAX. Поэтому я написал перехватчик, чтобы сделать трюк:
Угловой 2 (JavaScript)
app.config( function( $httpProvider ) {
$httpProvider.interceptors.push( function( $q, $rootScope ) {
return {
'request': function( config ) {
// Convert request URL for Juniper Secure Web Access
if ( typeof DanaUrl === "function" && !config.url.includes( '.html' ) ) {
config.url = DanaUrl( config.url );
}
return config;
}
};
} );
} );
Угловой 5+ (TypeScript)
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
declare function DanaUrl(url: string): string;
@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
constructor(
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Rewrite Juniper SWA URLs
if ( typeof DanaUrl === "function" && !request.url.includes( '.html' ) ) {
request = request.clone({
url: DanaUrl( request.url )
});
}
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// do stuff with response if needed
}
}, (err: HttpErrorResponse) => {
}).finally(() => {
});
}
}
URL-адреса будут переписаны, если функция Juniper DanaURL доступна и URL-адрес не включен с ".html". Это связано с тем, что Angular использует URL-адреса для включения представлений в шаблон, даже если они включены (например, в теги сценария). (Мне не нравится эта часть, но пока она работает...)
Я надеюсь, что это полезно для кого-то...
Мы решили эту проблему, исправив функцию parseAppUrl в базовой кодовой базе Angular.js следующим образом:
function parseAppUrl(relativeUrl, locationObj, appBase) {
var prefixed = (relativeUrl.charAt(0) !== '/');
if (prefixed) {
relativeUrl = '/' + relativeUrl;
}
var match = urlResolve(relativeUrl, appBase);
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
match.pathname.substring(1) : match.pathname);
locationObj.$$search = parseKeyValue(match.search);
locationObj.$$hash = decodeURIComponent(match.hash);
//Detect Juniper re-write functions and handle the $$path issue
if(locationObj.$$path === "[object Object]" && typeof(DanaOrigUrl) === 'function') {
var __strH = 'href';
var __tmpHack = match[__strH];
var __nn = ("" + __tmpHack).match(/^(https?:\/\/[^\/]+)?([^?|#]*)/);
locationObj.$$path = __nn[2];
}
// make sure path starts with '/';
if (locationObj.$$path && locationObj.$$path.charAt(0) != '/') {
locationObj.$$path = '/' + locationObj.$$path;
}
}