2013-09-06 8 views
14

Jestem bardzo początkującym użytkownikiem AngularJS, a teraz spędzam 3 dni na znajdowaniu sposobu na obsłużenie statusu 401. Próbowałem przechwytywaczy, używając $ http, używając $ resource ... ale nic nie działa. Moja aplikacja wywołuje wywołanie JSONP na tym samym serwerze. gdy wystąpi błąd, zostaje wykryty w funkcji wywołania błędu. ale status ma zawsze wartość 0, a odpowiedź jest niezdefiniowana.401 Nieautoryzowana obsługa błędów w AngularJS

Najpierw próbowałem to przechwytywacza

app.config(['$httpProvider', function($httpProvider) { 
$httpProvider.responseInterceptors.push(['$q', function($q) { 
    return function(promise) { 
     return promise.then(function(response) { 
      console.log('success in interceptor'); 
      return response; 
     }, function(response) { 
      console.log('error in interceptor'); 
      console.log(response); 
      if (response.status === 401) { 
       response.data = { 
        status: false, 
        description: 'Authentication required!' 
       }; 
       return response; 
      } 
      return $q.reject(response); 
     }); 
    } 
}]); 
}]); 

Po drugie, również próbował w sterownikach użyciu $ zasób

$scope.fetchData = function(fromDate, toDate){ 
     Cancel.get({from: fromDate, to: toDate, perPage: 99999}, 
        function(data){        
         $scope.cancels = $scope.filteredCancels = data.data; 
         $scope.search(); 
        }, 
        function(response) { 
         $scope.errorMessage = '<h4>Error : '+response.status+'</h4>'; 
         window.location = "/"; 
        });    
     }; 

trzecie, wypróbowane przy użyciu $ http zamiast $ zasobu

$scope.fetchData = function(fromDate, toDate){ 
    $http.jsonp('http://host:8900/api/cancellations?callback=JSON_CALLBACK') 
     .success(function(data, status, headers, config) { 
      console.log(status); 
      }) 
     .error(function(data, status, headers, config) { 
      console.log(status);    
      }; 

Oto informacje o nagłówku dla wywołania JSONP

Request URL:http://host:8900/api/cancellations?callback=angular.callbacks._0 
Request Method:GET 
Status Code:401 Unauthorized 
Request Headersview source 
Accept:*/* 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6 
Cache-Control:max-age=0 
Connection:keep-alive 
Cookie:__utma=149207145.339724205.1374885003.1377550245.1378313049.3; __utmc=149207145; __utmz=149207145.1378313049.3.2.utmcsr=cyphersmart.qc3deva.electricmail.com:8900|utmccn=(referral)|utmcmd=referral|utmcct=/; remember_username=elie.kim%40electricmail.com; PHPSESSID=gdoemlp5jltqq62etc5gfuh653; cookie=cookiecheck; __utma=1.789184132.1378340585.1378499390.1378504453.10; __utmb=1.3.10.1378504453; __utmc=1; __utmz=1.1378340585.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) 
Host:host:8900 
Referer:http://host:8900/reports/cancels/ 
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22 
Query String Parametersview sourceview URL encoded 
callback:angular.callbacks._0 
Response Headersview source 
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Connection:keep-alive 
Content-Type:application/json; charset=utf-8 
Date:Fri, 06 Sep 2013 22:02:13 GMT 
Expires:Thu, 19 Nov 1981 08:52:00 GMT 
Keep-Alive:timeout=20 
Pragma:no-cache 
Server:nginx/0.7.65 
Transfer-Encoding:chunked 

Nie mogłem znaleźć sposobu na obsłużenie nieautoryzowanego statusu 401, jednak wszystko naprawiłem. Byłbym bardzo wdzięczny, gdybym mógł otrzymać wskazówkę lub dobrą radę.

+0

jeśli ciebie nawigować do adresu URL w przeglądarce, co się dzieje? – akonsu

+0

Jaką wersję kąta używasz? Jest to ważne, ponieważ zmieniono parametr 'responseInterceptors' w wersji 1.2 – TheSharpieOne

+0

@SharpieOne, moja wersja to v1.0.6. czy to jest powód? –

Odpowiedz

4

muszę zrobić bardzo podobny niedawno, tu jest mój przechwytujących

app.factory("HttpErrorInterceptorModule", ["$q", "$rootScope", "$location", 
    function($q, $rootScope, $location) { 
     var success = function(response) { 
      // pass through 
      return response; 
     }, 
      error = function(response) { 
       if(response.status === 401) { 
        // dostuff 
       } 

       return $q.reject(response); 
      }; 

     return function(httpPromise) { 
      return httpPromise.then(success, error); 
     }; 
    } 
]).config(["$httpProvider", 
    function($httpProvider) { 
     $httpProvider.responseInterceptors.push("HttpErrorInterceptorModule"); 
    } 
]); 

zmodyfikowany lekki dla przypadku użycia

2

Follows podobne rozwiązanie ...

angular.module('myApp', ['myApp.services', 'myApp.directives'], function ($routeProvider, $locationProvider, $httpProvider, $location) { 

    var httpInterceptor = ['$rootScope', '$q', function (scope, $q) { 

     function success(response) { 
      return response; 
     } 

     function error(response) { 
      var status = response.status; 

      if (status == 401) { 
       $location.url('/login'); 
       return; 
      } 

      return $q.reject(response); 

     } 

     return function (promise) { 
      return promise.then(success, error); 
     } 

    }]; 
    $httpProvider.responseInterceptors.push(httpInterceptor); 
}); 
+0

$ httpProvider.interceptors.push ("HttpErrorInterceptorModule"); – Krack

2

W przypadku każde wywołanie API zwraca 401 musimy przekierować użytkownika do strony logowania. Przechwytywacz HTTP Angular jest świetny do tej pracy. Jak widać z app.js powyżej, to został zepchnięty do rury tutaj:

httpProvider.responseInterceptors.push('httpInterceptor'); 

Realizacja przechwytujących sama,

'use strict'; 

angular.module('dashboardApp').factory('httpInterceptor', function httpInterceptor ($q, $window, $location) { 
    return function (promise) { 
     var success = function (response) { 
      return response; 
     }; 

     var error = function (response) { 
      if (response.status === 401) { 
       $location.url('/login'); 
      } 

      return $q.reject(response); 
     }; 

     return promise.then(success, error); 
    }; 
}); 
+0

Jak pokazać użytkownikowi, kiedy przekierowanie do lokalizacji.path (/ login) powód, dla którego został wylogowany? – maumercado

4

Przyjęte rozwiązanie nie działa na nowszych wersjach kątowej. Korzystanie 1.5.x (a może nawet wcześniej), trzeba napisać przechwytywacza inaczej:

// http interceptor to handle redirection to login on 401 response from API 
app.factory('httpResponseInterceptor', ['$q', '$rootScope', '$location', function($q, $rootScope, $location) { 
    return { 
     responseError: function(rejection) { 
      if (rejection.status === 401) { 
       // Something like below: 
       $location.path('signin/invalidSession'); 
      } 
      return $q.reject(rejection); 
     } 
    }; 
}]); 

Nakładać:

app.config(function($httpProvider) { 
    $httpProvider.interceptors.push('httpResponseInterceptor'); 
}); 

Patrz tutaj dla dalszych informacji https://docs.angularjs.org/api/ng/service/ $ http # przechwytujących