2015-02-05 3 views
0

В настоящее время я пытаюсь кэшировать информацию пользователя. Я даю вам ребятам сценарий происходящего.Кэширование с AngularJs

пользователь пытается войти в систему с учетной записью A. Имя учетной записи A появляется на навигационной панели. После того, как пользователь выйдет из системы и попытается войти в систему с учетной записью B, на самой панели навигации имя по-прежнему принадлежит имени учетной записи A.

Код

service.js

.factory('Auth', function($http, $q, AuthToken) { 

    // create auth factory object 
    var authFactory = {}; 

    // log a user in 
    authFactory.login = function(username, password) { 

     // return the promise object and its data 
     return $http.post('/api/login', { 
      username: username, 
      password: password 
     }) 
     .success(function(data) { 
      AuthToken.setToken(data.token); 
      return data; 
     }); 
    }; 

    // log a user out by clearing the token 
    authFactory.logout = function() { 
     // clear the token 
     AuthToken.setToken(); 
    }; 

    // check if a user is logged in 
    // checks if there is a local token 
    authFactory.isLoggedIn = function() { 
     if (AuthToken.getToken()) 
      return true; 
     else 
      return false; 
    }; 

    // get the logged in user 
    authFactory.getUser = function() { 
     if (AuthToken.getToken()) 
      return $http.get('/api/me', {cache: true}); 
     else 
      return $q.reject({ message: 'User has no token.' });   
    }; 

    // return auth factory object 
    return authFactory; 

}) 

// =================================================== 
// factory for handling tokens 
// inject $window to store token client-side 
// =================================================== 
.factory('AuthToken', function($window) { 

    var authTokenFactory = {}; 

    // get the token out of local storage 
    authTokenFactory.getToken = function() { 
     return $window.localStorage.getItem('token'); 
    }; 

    // function to set token or clear token 
    // if a token is passed, set the token 
    // if there is no token, clear it from local storage 
    authTokenFactory.setToken = function(token) { 
     if (token) 
      $window.localStorage.setItem('token', token); 
     else 
      $window.localStorage.removeItem('token'); 
    }; 

    return authTokenFactory; 

}) 

// =================================================== 
// application configuration to integrate token into requests 
// =================================================== 
.factory('AuthInterceptor', function($q, $location, AuthToken) { 

    var interceptorFactory = {}; 

    // this will happen on all HTTP requests 
    interceptorFactory.request = function(config) { 

     // grab the token 
     var token = AuthToken.getToken(); 

     // if the token exists, add it to the header as x-access-token 
     if (token) 
      config.headers['x-access-token'] = token; 

     return config; 
    }; 

    // happens on response errors 
    interceptorFactory.responseError = function(response) { 

     // if our server returns a 403 forbidden response 
     if (response.status == 403) 
      $location.path('/login'); 

     // return the errors from the server as a promise 
     return $q.reject(response); 
    }; 

    return interceptorFactory; 

}); 

controller.js

angular.module('mainCtrl', []) 

.controller('MainController', function($rootScope, $location, Auth) { 

    var vm = this; 

    // get info if a person is logged in 
    vm.loggedIn = Auth.isLoggedIn(); 

    // check to see if a user is logged in on every request 
    $rootScope.$on('$routeChangeStart', function() { 
     vm.loggedIn = Auth.isLoggedIn();  

     // get user information on page load 
     Auth.getUser() 
      .then(function(data) { 
       vm.user = data.data; 
      }); 
    }); 

    // function to handle login form 
    vm.doLogin = function() { 
     vm.processing = true; 

     // clear the error 
     vm.error = ''; 

     Auth.login(vm.loginData.username, vm.loginData.password) 
      .success(function(data) { 
       vm.processing = false; 

       // get user information on page load 
       Auth.getUser() 
        .then(function(data) { 
         vm.user = data.data; 
        }); 

       // if a user successfully logs in, redirect to users page 
       if (data.success) 
        $location.path('/'); 
       else 
        vm.error = data.message; 
      }); 
    }; 

    // function to handle logging out 
    vm.doLogout = function() { 
     Auth.logout(); 
     $location.path('/logout'); 
    }; 

}); 

index.html

<ul class="nav navbar-nav navbar-right"> 
      <li ng-if="!main.loggedIn"><a href="/login">Login</a></li> 
      <li ng-if="main.loggedIn"><a href="#">Hello {{ main.user.username }}</a></li> 
      <li ng-if="main.loggedIn"><a href="#" ng-click="main.doLogout()">Logout</a></li> 
      <li><a href=""><button class="btn btn-primary">Write</button></a></li> 
     </ul> 

Так в основном мое предположение, что проблема заключается в service.js w здесь я добавил кэш: true. Нужно ли мне добавить к нему какую-то логику?

+1

Если бы вы положили это на рабочий Plunk на plnkr.co, это сделало бы его намного легче отлаживать. –

+0

изменить $ http.get ('/ api/me', {cache: true}); до $ http.get ('/ api/me? rand =' + Math.random(), {cache: true}); –

+0

Я предполагаю, что index.html не является полным? Вы используете ng-controller = «MainController as main»? –

ответ

1

В вашем приложении могут быть два разных кеша. Во-первых, это угловая кэш, который вы установили ниже {кэша: истинно}

authFactory.getUser = function() { 
    if (AuthToken.getToken()) 
     return $http.get('/api/me', {cache: true}); 
    else 
     return $q.reject({ message: 'User has no token.' });   
}; 

Этот кэш только там на время приложения, как только вы покинете или обновите страницу, это пошло!

Другой кэш, который является кешем браузера, немного сложнее иметь дело. Обратите внимание, что это не имеет отношения к Угловому кешу, поэтому, если это ваша проблема, просто отключите {cache: false}, не помогите. Чтобы предотвратить кеш, вам нужно будет отправить список различных заголовков кеширования в ваш ненадежный API, и это может не всегда работать.

Самый простой способ предотвратить кеш - добавить версию к вашему URL-адресу, которая на самом деле не влияет на ваши результаты, но позволяет вашему браузеру думать, что это другой URL-адрес. Это называется Cache Busting.

Самый простой способ кэширования бюста - добавить Math.Random() для добавления к URL-адресу. Шансы Math.Random быть одинаковыми, вероятно, в миллиардах.

authFactory.getUser = function() { 
    if (AuthToken.getToken()) 
     return $http.get('/api/me?rand=' + Math.random(), {cache: true}); 
    else 
     return $q.reject({ message: 'User has no token.' });   
}; 

Однако, если вы хотите, лучший способ сделать это специфично для вашего приложения, вы можете добавить имя пользователя в свой адрес. Таким образом, он будет кэшироваться для одних и тех же пользователей, что означает, что вы фактически используете механизм кэширования и не привязываетесь к нему!

authFactory.getUser = function() { 
    if (AuthToken.getToken()) 
     return $http.get('/api/me?user=' + <username>, {cache: true}); 
    else 
     return $q.reject({ message: 'User has no token.' });   
}; 
+0

Это ответ потрясающий, но прежде чем я приму свой ответ, мне нужно задать вам последний вопрос. В последнем примере, который вы написали, я получил ошибку, когда я ее реализовал. В моем токене есть имя пользователя, в чем проблема? – airsoftFreak

+0

Я проверяю консоль, и она говорит о неожиданном токене. Я предполагаю, что ** ** является виновником. – airsoftFreak

+0

my - это просто значение placeholder, вам может потребоваться фактически ввести переменную имени пользователя –

Смежные вопросы