离子:没有内容/白屏使用拦截器

时间:2015-06-03 07:31:04

标签: angularjs cordova ionic-framework ionic

我成功设法在我的Ionic应用程序中使用拦截器(AngularJs)。 Previous post

虽然它在浏览器中使用"离子服务"。

完美地工作

使用" ionic run android"标题标题和内容块(" ion-content")中没有加载内容。 (要么在genymotion上模仿,要么在我自己的手机上模仿)。见下面的截图。

no content / white screen using interceptors

我很确定它来自我使用的拦截器,因为在此之前,应用程序正在任何平台上运行。此外,一旦我移除拦截器它再次工作。这是代码。

请注意,我正在检查哪个网址被调用,因此我不会进入循环依赖关系或检查无用的网址,只有对我的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;

    }
};

})

1 个答案:

答案 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);

如果您想了解有关拦截器的更多信息,可以read these blogs