Угловая маршрутизация веб-приложений в 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;
  }
}

Ссылка: https://github.com/angular/angular.js/issues/8905

Другие вопросы по тегам