5

각도 $ http 인터셉터를 사용하여 ajax 요청이 401 (인증되지 않음)을 반환하는지 확인합니다. 응답이 401이면 원래 요청이 대기 상태가되고 로그인 양식이 표시되며 로그인에 성공하면 대기중인 요청을 다시 시도합니다. 이것은 이미 $의 http로 작동하고, 각 인터셉터의 소스는 다음과 같습니다

define('common.service.security.interceptor', ['angular'], function() { 
'use strict'; 

angular.module('common.service.security.interceptor', ['common.service.security.retryQueue']) 

.factory('securityInterceptor', [ 
    '$injector', 
    '$location', 
    'securityRetryQueue', 
    function($injector, $location, securityRetryQueue) { 

     return function(promise) { 

      var $http = $injector.get('$http'); 


      // catch the erroneous requests 
      return promise.then(null, function(originalResponse){ 
       if(originalResponse.status === 401){ 
        promise = securityRetryQueue.pushRetryFn('Unauthorized', function retryRequest(){ 
         return $injector.get('$http')(originalResponse.config); 
        }); 
       } 

       return promise; 
      }); 
     }; 
    } 
]) 

// register the interceptor to the angular http service. method) 
.config(['$httpProvider', function($httpProvider) { 
    $httpProvider.responseInterceptors.push('securityInterceptor'); 

}]);}); 

가 어떻게 바람 요청이 각 $에 http 인터셉터를 사용하여 만들 수 있습니까?

Breeze는 "Breeze/Adapters/breeze.ajax.angular.js"파일에서 각 $ http 서비스에 대한 래퍼를 제공합니다.

angular.js 디버깅
breeze.config.initializeAdapterInstance("ajax", "angular", true); 

는, 지금 사실 바람이 $ HTTP를 사용하는 것을 알 수 있지만, 위의 등록 된 인터셉터를 실행하지 않습니다 그래서 첫 번째 아이디어는 그것을 사용하는 바람을 이야기했다. $ http 안에는 등록 된 인터셉터를 저장하는 배열 "reversedInterceptors"가 있습니다. 이 배열을 콘솔에 기록합니다. $ http를 사용하면이 배열의 길이는 (예상대로) 1이지만 breeze로 요청할 때이 배열은 비어 있습니다.

질문 : 어떻게이 $ http 인터셉터를 breeze 요청과 함께 사용할 수 있습니까? 여기

날 바람 각도 아약스 어댑터와 함께 HTTP 인터셉터를 사용하기 위해 setHttp 방법이 작동하여 바람

define('breeze.ajax.angular.module', ['breeze', 'angular'], function (breeze) { 
'use strict'; 
/* jshint ignore:start */ 
var core = breeze.core; 

var httpService; 
var rootScope; 

var ctor = function() { 
    this.name = "angular"; 
    this.defaultSettings = {}; 
}; 

ctor.prototype.initialize = function() { 

    var ng = core.requireLib("angular"); 

    if (ng) { 
     var $injector = ng.injector(['ng']); 
     $injector.invoke(['$http', '$rootScope', 
      function (xHttp, xRootScope) { 
       httpService = xHttp; 
       rootScope = xRootScope; 
     }]); 
    } 

}; 

ctor.prototype.setHttp = function (http) { 
    httpService = http; 
    rootScope = null; // to suppress rootScope.digest 
}; 

ctor.prototype.ajax = function (config) { 
    if (!httpService) { 
     throw new Error("Unable to locate angular for ajax adapter"); 
    } 
    var ngConfig = { 
     method: config.type, 
     url: config.url, 
     dataType: config.dataType, 
     contentType: config.contentType, 
     crossDomain: config.crossDomain 
    } 

    if (config.params) { 
     // Hack: because of the way that Angular handles writing parameters out to the url. 
     // so this approach takes over the url param writing completely. 
     // See: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/ 
     var delim = (ngConfig.url.indexOf("?") >= 0) ? "&" : "?"; 
     ngConfig.url = ngConfig.url + delim + encodeParams(config.params); 
    } 

    if (config.data) { 
     ngConfig.data = config.data; 
    } 

    if (!core.isEmpty(this.defaultSettings)) { 
     var compositeConfig = core.extend({}, this.defaultSettings); 
     ngConfig = core.extend(compositeConfig, ngConfig); 
    } 

    httpService(ngConfig).success(function (data, status, headers, xconfig) { 
     // HACK: because $http returns a server side null as a string containing "null" - this is WRONG. 
     if (data === "null") data = null; 
     var httpResponse = { 
      data: data, 
      status: status, 
      getHeaders: headers, 
      config: config 
     }; 
     config.success(httpResponse); 
    }).error(function (data, status, headers, xconfig) { 
     var httpResponse = { 
      data: data, 
      status: status, 
      getHeaders: headers, 
      config: config 
     }; 
     config.error(httpResponse); 
    }); 
    rootScope && rootScope.$digest(); 
}; 

function encodeParams(obj) { 
    var query = ''; 
    var key, subValue, innerObj; 

    for (var name in obj) { 
     var value = obj[name]; 

     if (value instanceof Array) { 
      for (var i = 0; i < value.length; ++i) { 
       subValue = value[i]; 
       fullSubName = name + '[' + i + ']'; 
       innerObj = {}; 
       innerObj[fullSubName] = subValue; 
       query += encodeParams(innerObj) + '&'; 
      } 
     } else if (value instanceof Object) { 
      for (var subName in value) { 
       subValue = value[subName]; 
       fullSubName = name + '[' + subName + ']'; 
       innerObj = {}; 
       innerObj[fullSubName] = subValue; 
       query += encodeParams(innerObj) + '&'; 
      } 
     } else if (value !== undefined) { 
      query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; 
     } 
    } 

    return query.length ? query.substr(0, query.length - 1) : query; 
} 


breeze.config.registerAdapter("ajax", ctor); 

breeze.config.initializeAdapterInstance("ajax", "angular", true); 
/* jshint ignore:end */ 
}); 

답변

6

에 의해 제공 breeze.ajax.angular.js 코드입니다. 내 환경에서, 그것은 다음과 같습니다

(function() { 
    'use strict'; 

    var serviceId = 'entityManagerFactory'; 
    angular.module('app').factory(serviceId, ['$http', emFactory]); 

    function emFactory($http) { 

     var instance = breeze.config.initializeAdapterInstance("ajax", "angular"); 
     instance.setHttp($http); 

     ... 

    } 
})(); 

난 정말이에 대한 정보가 download 페이지 1.4.4 릴리스 노트에서 발견 한 유일한 장소. 나는 이것이 실제로 무엇을하는지 이해하지 못한다. 나는 산들 바람 한 사람 중 한 명이 더 나은 설명을 할 것이라고 확신합니다.

+0

빙고! @ almaplayer. 'setHttp' FTW. 아래 내 대답을 참조하십시오. – Ward

4

@almaplayera에 설명 된대로 setHttp($http)으로 전화해야합니다. 그의 대답을 정답으로 표시하십시오.

이것이 필요한 이유입니다.

기본적으로 breeze angles ajax 어댑터는 $ http의 모든 인스턴스를 사용할 수 있도록 초기화합니다. 아쉽게도 대부분의 스크립트가로드 될 때 $http 인스턴스가 생성되지 않았습니다. 그것은 모듈이로드 될 때까지 발생하지 않습니다 ... 일반적으로 바람이 부는 후에 오랫동안 발생합니다.

전혀 작동하지 않는 어댑터를 만드는 대신 breeze는 자체 인스턴스 인 $http을 회전시키고 각형 아약스 어댑터를 해당 인스턴스에 연결합니다.

코드가 특별한 작업을 수행하지 않으면 정상적으로 작동합니다. 최적이 아닙니다. 필요한 것보다 하나 더 여분의 $digest을 얻을 수 있습니다. 그러나 그것은 대부분의 사람들에게 효과적이며, 처리 할 수있는 구성 노이즈 이상은 존재 함을 인정합시다.

하지만 뭔가 특별한 일을하고 있습니다. breeze가 만든 인스턴스가 아닌 $http의 매우 구체적인 인스턴스를 구성하고 있습니다.

따라서 breeze에게 $http의 인스턴스를 사용하도록 알려야합니다.그리고 그것은 당신이 setHttp($http)라고 부를 때 일어나는 일입니다.

이 의견 덕분에 breeze documentation on ajax adapters을 업데이트하여 각도 앱을 구성하는 방법을 설명했습니다.

관련 문제