我成功设法在我的Ionic应用程序中使用拦截器(AngularJs)。 Previous post。
虽然它在浏览器中使用"离子服务"。
完美地工作使用" ionic run android"标题标题和内容块(" ion-content")中没有加载内容。 (要么在genymotion上模仿,要么在我自己的手机上模仿)。见下面的截图。
我很确定它来自我使用的拦截器,因为在此之前,应用程序正在任何平台上运行。此外,一旦我移除拦截器它再次工作。这是代码。
请注意,我正在检查哪个网址被调用,因此我不会进入循环依赖关系或检查无用的网址,只有对我的api的调用才能通过。
app.config(function($httpProvider){
$httpProvider.interceptors.push(['$location', '$injector', '$q', function($location, $injector, $q){
return {
'request' : function(config){
// intercept request
// carefull includes might not work while emulating
// use instead indexOf for that case
if(!config.url.includes('/oauth/v2/token') && config.url.includes('/api')){
// inject the service manually
var OauthService = $injector.get('OauthService');
var access_token = OauthService.token();
config.url = config.url+'?access_token='+access_token.key;
}
return config;
}
}
}]);
});
任何可能导致此错误的想法? (顺便说一句,控制台在浏览器上没有显示任何错误。)
更新:
OauthService.js:
app.factory('OauthService', function($http, $localStorage) {
return {
token : function(){
// Store actual token
access_token = $localStorage.getObject('access_token');
// Store actual identity
identity_token = $localStorage.getObject('identity_token');
// IF no user logged
if(isObjectEmpty(identity_token)){
// IF access_token does NOT exist OR will expires soon
if( isObjectEmpty(access_token) || Date.now() > (access_token.expires_at - (600*1000)) ){
// Create an anonymous access_token
return $http
.get(domain+'/oauth/v2/token?client_id='+public_id+'&client_secret='+secret+'&grant_type=client_credentials')
.then(function (response) {
$localStorage.setObject('access_token', {
key: response.data.access_token,
type: 'anonymous',
expires_at: Date.now()+(response.data.expires_in*1000)
});
return response.data.access_token;
});
}
}
// IF user is logged
else{
// IF access_token does NOT exist OR will expires soon OR is anonymous
if( isObjectEmpty(access_token) || Date.now() > (access_token.expires_at - (600*1000)) || access_token.type == 'anonymous' ){
// Create an access_token with an identity
return $http
.get(domain+'/oauth/v2/token?client_id='+public_id+'&client_secret='+secret+'&api_key='+identity_token+'&grant_type=http://oauth2.dev/grants/api_key')
.then(function (response) {
$localStorage.setObject('access_token', {
key: response.data.access_token,
type: 'identity',
expires_at: Date.now()+(response.data.expires_in*1000)
});
return response.data.access_token;
});
}
}
return access_token.key;
}
};
})
答案 0 :(得分:3)
您安装了cordova whitelist plugin吗?
cordova plugin add cordova-plugin-whitelist
或者如果要保存对config.xml文件的引用:
cordova plugin add cordova-plugin-whitelist --save
如果您没有,您的设备将无法访问外部资源。
您可以找到更多信息here。
<强>更新强>:
我已经检查了你以前的答案 拦截器的想法是拦截对外部服务的调用,在管道中插入一些动作。
我会改变你的拦截器:
$httpProvider.interceptors.push(['$location', '$injector', '$q', '$localStorage', function($location, $injector, $q, $localStorage){
return {
'request' : function(config) {
config.headers = config.headers || {};
access_token = $localStorage.getObject('access_token');
if (access_token) {
config.headers.Authorization = 'Bearer ' + access_token;
}
}
'response' : function(response){
if (response.status === 401) {
logger.debug("Response 401");
}
return response || $q.when(response);
}
'responseError' : function(rejection){
if (rejection.status === 401) {
var OauthService = $injector.get('OauthService');
var access_token = OauthService.token();
if (access_token === null)
{
return $q.reject(rejection);
}
// Append your access token to the previous request and re-submits.
rejection.config.headers['Authorization'] = 'Bearer ' + access_token;
return $injector.get('$http')(rejection.config);
}
// This is necessary to make a `responseError` interceptor a no-op.
return $q.reject(rejection);
}
}
}]);
如果您查看上面的拦截器,它会管理对外部资源(REST api)的所有请求,并在需要时将承载令牌附加到授权标头。
响应没有太大作用,因为它仅用于记录目的。
responseError
是您应该拦截并检查您的令牌是否过期的地方,获取新的令牌并重新提交请求。
我们检查用户是否未获得该请求的授权:
if (rejection.status === 401) { ... }
如果不是,我们会请求新的访问令牌。我猜你的 OauthService 会这样做。 如果我们有新的访问令牌:
var access_token = OauthService.token();
我们可以再次将访问令牌附加到请求标头:
rejection.config.headers['Authorization'] = 'Bearer ' + access_token;
并重新提交上一个请求:
return $injector.get('$http')(rejection.config);