Trình xử lý lỗi Ajax toàn cầu với AngularJS


82

Khi trang web của tôi là 100% jQuery, tôi đã từng làm điều này:

$.ajaxSetup({
    global: true,
    error: function(xhr, status, err) {
        if (xhr.status == 401) {
           window.location = "./index.html";
        }
    }
});

để đặt trình xử lý toàn cục cho lỗi 401. Bây giờ, tôi sử dụng anglejs với $resource$httpđể thực hiện các yêu cầu (REST) ​​của mình tới máy chủ. Có cách nào để đặt tương tự một trình xử lý lỗi toàn cục với góc không?


Nó có thể là bản sao của AngularJS Failed Resource GET không?
MilkyWayJoe

1
Không, chúng tôi muốn làm một xử lý lỗi 401 toàn cầu đối với các ứng dụng
cricardol

lol, bạn đã xem đó là thứ bạn muốn nhưng với trạng thái http khác (bạn có thể thay đổi) chưa? Nhưng dù sao, pkozlowski.opensource của câu trả lời cho thấy bạn làm thế nào để làm điều đó
MilkyWayJoe

Không, nó là rất nhiều giống như câu trả lời của Justen ... Đây không phải là một trùng lặp với các câu hỏi mà bạn đang nói
cricardol

Câu trả lời:


97

Tôi cũng đang xây dựng một trang web với góc cạnh và tôi đã gặp phải trở ngại tương tự đối với việc xử lý 401 toàn cầu. Tôi đã kết thúc bằng cách sử dụng trình chặn http khi tôi xem bài đăng trên blog này. Có lẽ bạn sẽ thấy nó hữu ích như tôi đã làm.

"Xác thực trong ứng dụng dựa trên AngularJS (hoặc tương tự)." , phần mềm espeo

CHỈNH SỬA: giải pháp cuối cùng

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

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

        function success(response) {
            return response;
        }

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

            if (status == 401) {
                window.location = "./index.html";
                return;
            }
            // otherwise
            return $q.reject(response);

        }

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

    }];
    $httpProvider.responseInterceptors.push(interceptor);

4
Cần trả về $ q.reject (phản hồi); khi tình trạng == 401, để tránh một góc lỗi ồn ào
s_t_e_v_e

1
@daniellmb. Nó phụ thuộc. Nếu bạn thực sự muốn chuyển đến một trang khác, không chỉ thay đổi chế độ xem thì bạn thực sự nên sử dụng $ window. Nếu trang đăng nhập của bạn chỉ là một cái nhìn và điều khiển với góc của bạn thì bạn có thể sử dụng $ location.path
uriDium

1
@uriDium đúng, quan điểm của tôi là sử dụng các đối tượng được cung cấp góc cạnh để bạn có thể mô phỏng và kiểm tra.
daniellmb

22
$ httpProvider.responseInterceptors hiện không được dùng nữa. Xem docs.angularjs.org/api/ng.$http#description_interceptors .
quartzmo

1
Để thành công, bạn cần trả về như return response || $q.when(response);vậy để nếu phản hồi trống thì đối tượng hứa cũng được trả về.
Bò tót Ashish

77

Xin lưu ý rằng responseInterceptors đã không được chấp nhận với Angular 1.1.4. Dưới đây, bạn có thể tìm thấy một đoạn trích dựa trên các tài liệu chính thức , cho thấy cách mới để triển khai các bộ đánh chặn.

$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
  return {
    'response': function(response) {
      // do something on success
      return response || $q.when(response);
    },

   'responseError': function(rejection) {
      // do something on error
      if (canRecover(rejection)) {
        return responseOrNewPromise;
      }
      return $q.reject(rejection);
    }
  };
});

$httpProvider.interceptors.push('myHttpInterceptor');

Đây là cách nó trông như thế nào trong dự án của tôi bằng cách sử dụng Coffeescript:

angular.module("globalErrors", ['appStateModule']).factory "myHttpInterceptor", ($q, $log, growl) ->
  response: (response) ->
    $log.debug "success with status #{response.status}"
    response || $q.when response

  responseError: (rejection) ->
    $log.debug "error with status #{rejection.status} and data: #{rejection.data['message']}"
    switch rejection.status
      when 403
        growl.addErrorMessage "You don't have the right to do this"
      when 0
        growl.addErrorMessage "No connection, internet is down?"
      else
        growl.addErrorMessage "#{rejection.data['message']}"

    # do something on error
    $q.reject rejection

.config ($provide, $httpProvider) ->
  $httpProvider.interceptors.push('myHttpInterceptor')

Nhưng bạn sẽ không có dữ liệu xhr hoặc thông tin hữu ích khác trong trình đánh chặn responseError. Nó thậm chí không thể sử dụng được để quyết định xem nó có thể khôi phục được hay không.
zw0rk

1
@ zw0rk Bạn sẽ ... bên trong responseError, rejectioncó mọi thứ bạn cần.
Langdon

Dòng cuối cùng đó, $httpProvider...có được gói trong một config()khối không?
delwin

thực sự, tôi đã chỉnh sửa câu trả lời của mình để chỉ ra cách tôi đã thực hiện nó trong dự án của mình bằng cách sử dụng Coffeescript. Sử dụng js2coffee.org nếu bạn thích nó bằng Javascript.
MikeR

Nên không phải tất cả các tham chiếu đến responsethuộc responseErrorchức năng thực sự là tài liệu tham khảo để rejection(hoặc có thể tham số nên đã thay đổi tên của nó để response?
Adam Nofsinger

16

Tạo tệp <script type="text/javascript" src="../js/config/httpInterceptor.js" ></script>với nội dung này:

(function(){
  var httpInterceptor = function ($provide, $httpProvider) {
    $provide.factory('httpInterceptor', function ($q) {
      return {
        response: function (response) {
          return response || $q.when(response);
        },
        responseError: function (rejection) {
          if(rejection.status === 401) {
            // you are not autorized
          }
          return $q.reject(rejection);
        }
      };
    });
    $httpProvider.interceptors.push('httpInterceptor');
  };
  angular.module("myModule").config(httpInterceptor);
}());

@ThilakRaj đoạn mã trên sẽ chạy trên mọi yêu cầu http. Vì vậy, hãy tạo hai điểm ngắt trong Chrome, một ở dòng ´return response´ và một ở dòng ´return $ q.reject´ để kiểm tra xem nó có chạy như bình thường không.
Jan-Terje Sørensen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.