Angular web应用在Juniper SSL VPN中的路由



目前我正在使用AngularJS开发一个简单的web应用程序。在开发过程中,我在应用程序由IIS本地服务时对其进行了测试。然而,当我把它部署到公司的web服务器上,并在Juniper SSL VPN中运行它时,问题就开始了。

首先,我必须应用以下"修复":在Juniper SSL VPN中运行AngularJS路由失败#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测试过了。

任何帮助解决这个问题是非常感谢的!

可以通过配置Juniper作为反向代理来解决这个问题。

我们通过修补Angular.js核心代码库中的parseAppUrl函数来解决这个问题,如下所示:

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

在我的例子中,我在重写url时遇到了问题。网关在处理标准HTML href属性时做得很好,但在处理Angular AJAX调用时却做得不好。所以我写了一个拦截器来完成这个任务:

Angular 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;
      }
    };
  } );
} );
Angular 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(() => {
    });
}

}

如果Juniper的DanaURL功能可用,且URL不包含"。html",则URL将被重写。这是因为Angular使用url将视图包含到模板中,即使它们已经被包含(例如在脚本标签中)。(我不喜欢这部分,但现在它正在工作…)

最新更新