微风采用了棱角分明$ HTTP拦截器 [英] Breeze using angular $http interceptor
问题描述
我用一个角$ HTTP拦截,检查,如果一个Ajax请求返回401(未验证)。 如果响应是401,原来的请求被排队,登录窗体显示和登录成功后,它重试排队的请求。这已经与$ HTTP工作,和源角拦截器:
定义(common.service.security.interceptor',['角'],函数(){
使用严格的;
angular.module('common.service.security.interceptor',['common.service.security.retryQueue'])
.factory('securityInterceptor',[
$喷油器',
$位置,
securityRetryQueue,
功能($注射器,$位置,securityRetryQueue){
复位功能(承诺){
变量$ HTTP = $ injector.get('$ HTTP');
//捕捉错误的请求
返回promise.then(NULL,函数(originalResponse){
如果(originalResponse.status === 401){
诺= securityRetryQueue.pushRetryFn('擅自',功能retryRequest(){
返回$ injector.get('$ HTTP)(originalResponse.config);
});
}
返回的承诺;
});
};
}
])
//注册拦截器的角度HTTP服务。方法)
的.config(['$ httpProvider',函数($ httpProvider){
$ httpProvider.responseInterceptors.push('securityInterceptor');
}]);});
我如何才能使用此角$ HTTP拦截微风请求?
微风提供了一个包装文件微风/适配器/ breeze.ajax.angular.js的角度$ http服务。因此,第一个想法是告诉轻而易举的使用它:
breeze.config.initializeAdapterInstance(AJAX,角,真正的);
调试angular.js,就表明其实微风使用$ HTTP,但它不执行上述注册拦截器。在$ HTTP,有一个数组reversedInterceptors,持有注册拦截器。我登录这个数组安慰。如果我使用$ HTTP,这个数组的长度为一个(如预期),但使得与清风请求时,该数组为空。
现在的问题是,我该如何使用这个$ HTTP拦截器与微风请求?
下面是$ C $下breeze.ajax.angular.js,由清风提供
定义(breeze.ajax.angular.module',['微风','角'],功能(清风){
使用严格的;
/ * jshint忽略:开始* /
VAR核心= breeze.core;
VAR的HTTPService;
VAR rootScope;
VAR构造函数=函数(){
this.name =角;
this.defaultSettings = {};
};
ctor.prototype.initialize =功能(){
变种NG = core.requireLib(角);
如果(纳克){
变量$注射器= ng.injector(['NG']);
$ injector.invoke(['$ HTTP,$ rootScope',
功能(xHttp,xRootScope){
HttpService的= xHttp;
rootScope = xRootScope;
}]);
}
};
ctor.prototype.setHttp =功能(HTTP){
HttpService的= HTTP;
rootScope = NULL; //为晚饭preSS rootScope.digest
};
ctor.prototype.ajax =功能(配置){
如果(!的HTTPService){
抛出新的错误(无法定位的角度对AJAX接口);
}
VAR ngConfig = {
方法:config.type,
网址:config.url,
数据类型:config.dataType,
的contentType:config.contentType,
跨域:config.crossDomain
}
如果(config.params){
因为那个角手柄写参数输出到URL的方式://哈克。
//所以这种方式接管了URL参数写入完全。
//参见:http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
VAR DELIM =(ngConfig.url.indexOf()&GT?; = 0)?与& :;?
ngConfig.url = ngConfig.url + DELIM + EN codeParams(config.params);
}
如果(config.data){
ngConfig.data = config.data;
}
如果(!core.isEmpty(this.defaultSettings)){
变种compositeConfig = core.extend({},this.defaultSettings);
ngConfig = core.extend(compositeConfig,ngConfig);
}
的HTTPService(ngConfig).success(功能(数据,状态,头,xconfig的){
// HACK:因为$ HTTP返回一个服务器端的空含有空的字符串 - 这是错误的。
如果(数据===空)的数据= NULL;
VAR HTT presponse = {
数据:数据,
状态:状态,
getHeaders:头,
配置:配置
};
config.success(HTT presponse);
})错误(功能(数据,状态,头,xconfig的){
VAR HTT presponse = {
数据:数据,
状态:状态,
getHeaders:头,
配置:配置
};
config.error(HTT presponse);
});
rootScope&功放;&安培; rootScope $摘要()。
};
功能连接codeParams(OBJ){
VAR的查询='';
VAR键,子值,innerObj;
为(在OBJ VAR名){
VAR值= OBJ [名]
如果(值的instanceof阵列){
对于(VAR I = 0; I< value.length ++我){
子值=值[I]
fullSubName =名称+'['+ I +];
innerObj = {};
innerObj [fullSubName] =子值;
查询+ = EN codeParams(innerObj)+'&放大器;';
}
}否则,如果(值的instanceof对象){
对(价值VAR子名){
子值=值[子名称]
fullSubName =名称+'['+子名称+];
innerObj = {};
innerObj [fullSubName] =子值;
查询+ = EN codeParams(innerObj)+'&放大器;';
}
}否则,如果(值!== undefined)的{
查询+ = EN codeURIComponent(名称)+=+ EN codeURIComponent(值)+'&放大器;';
}
}
返回query.length? query.substr(0,query.length - 1):查询;
}
breeze.config.registerAdapter(AJAX,构造函数);
breeze.config.initializeAdapterInstance(AJAX,角,真正的);
/ * jshint忽略:年底* /
});
使用setHttp方法适用于我使用HTTP拦截随着微风角阿贾克斯适配器。在我的环境中,它看起来是这样的:
(函数(){
使用严格的;
VAR服务ID ='的entityManagerFactory';
angular.module(应用程序)的工厂(服务ID,['$ HTTP,emFactory])。
功能emFactory($ HTTP){
VAR实例= breeze.config.initializeAdapterInstance(AJAX,角);
instance.setHttp($ HTTP);
...
}
})();
我真的发现有关这方面的消息的唯一地方是在发行说明1.4.4在下载页面。我真的不明白这是什么一样。我敢肯定的微风球员之一将有一个更好的解释。
I use a angular $http interceptor, to check if a ajax request returns 401 (not authenticated). If response is 401, the original request gets queued, a login form is shown and after login successfully, it retries the queued requests. This already works with $http, and the source for the angular interceptor is:
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');
}]);});
How can I make breeze request using this angular $http interceptor?
Breeze provides a wrapper for the angular $http service in the file "Breeze/Adapters/breeze.ajax.angular.js". So the first idea was to tell breeze to use it:
breeze.config.initializeAdapterInstance("ajax", "angular", true);
Debugging angular.js, it shows that breeze now in fact uses $http, but it does not execute the above registered interceptor. Inside $http, there is an array "reversedInterceptors", which holds the registered interceptors. I log this array to console. If i use $http, the length of this array is one (as expected), but when making request with breeze, this array is empty.
The question is, how can i use this $http interceptor with breeze requests?
Here is the code for breeze.ajax.angular.js, provided by breeze
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 */
});
using the setHttp method works for me to use http interceptors with the breeze angular ajax adapter. in my environment, it looks like this:
(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);
...
}
})();
the only place I've really found any information about this is in the release notes for 1.4.4 on the download page. I don't really understand what this does. i'm sure one of the breeze guys will have a better explanation.
这篇关于微风采用了棱角分明$ HTTP拦截器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!