2014-04-11 11 views
26

Tôi biết cách đánh chặn TẤT CẢ các yêu cầu, nhưng tôi chỉ muốn chặn các yêu cầu từ tài nguyên của mình.Làm thế nào để sử dụng chặn interularJS để chỉ chặn các yêu cầu http cụ thể?

Có ai biết cách thực hiện việc này không?

services.config(['$httpProvider',function($httpProvider) { 
    $httpProvider.interceptors.push('myHttpInterceptor'); 
}]); 

services.factory("userPurchased", function ($resource) { 
    return $resource("/api/user/purchases/:action/:item", 
     {}, 
     { 
      'list': {method: 'GET', params: {action: 'list'}, isArray: false}, 
      'save': {method: 'PUT', params: {item: '@item'}}, 
      'remove': {method: 'DELETE', params: {item: '@item'}}, 
     } 
    ); 
}); 

services.factory('myHttpInterceptor', function($q,$rootScope) { 
    // $rootScope.showSpinner = false; 
    return { 

     response: function(response) { 
     $rootScope.showSpinner = false; 
     // do something on success 
     console.log('success'); 
     console.log('status', response.status); 
     //return response; 
     return response || $q.when(response); 
     }, 

    responseError: function(response) { 
     // do something on error 
     $rootScope.showSpinner = true; 
     console.log('failure'); 
     console.log('status', response.status) 
     //return response; 
     return $q.reject(response); 
     } 
    }; 
    }); 

Trả lời

23

Nếu bạn muốn chặn chỉ yêu cầu từ các nguồn lực cụ thể, bạn có thể sử dụng tùy chọn interceptor tài sản của $request hành động. Góc của tài liệu see here (Sử dụng> hành động)

Javascript

angular.module('app', ['ngResource']). 
    factory('resourceInterceptor', function() { 
    return { 
     response: function(response) { 
     console.log('response intercepted: ', response); 
     } 
    } 
    }). 
    factory('resourceService', ['$resource', 'resourceInterceptor', function($resource, resourceInterceptor) { 
    return $resource(":name", 
     {}, 
     { 
      'list': {method: 'GET', isArray: false, interceptor: resourceInterceptor} 
     } 
    ); 
    }]). 
    run(['resourceService', '$http', function(resourceService, $http) { 
    resourceService.list({name: 'list.json'}); // <= intercepted 
    $http.get('list.json'); // <= not intercepted 
    }]); 

Plunker: http://plnkr.co/edit/xjJH1rdJyB6vvpDACJOT?p=preview

+0

Cảm ơn bạn - đây chính xác là những gì tôi đang tìm kiếm! – jrutter

+0

Chính xác những gì tôi cần! Cảm ơn! –

+0

Điều này không hoạt động khi tôi đẩy nhiều trình chặn vào httpProvider. Tôi muốn gọi chỉ là một interceptor riêng biệt, mà tôi đang làm như trên, nhưng phương pháp yêu cầu được gọi của tất cả các interceptors tôi đã đăng ký. – Sanket

23

Cách duy nhất tôi biết làm điều này là chỉ lọc ra các yêu cầu bạn muốn trong trình xử lý phản hồi.

ví dụ:

... 
response: function(response) { 
    if(response.config.url.startsWith('/api/')) { 
     //Do your custom processing here 
    } 

    return response; 
} 
... 

Polyfill cho string.startsWith()

//Taken from http://stackoverflow.com/questions/646628/javascript-startswith 
if (typeof(String.prototype.startsWith) === 'undefined') { 
    String.prototype.startsWith = function(str) { 
     return this.slice(0, str.length) === str; 
    }; 
} 
+5

1 cho đoạn polyfill ghi – Vadim

+3

Nếu bạn đang sử dụng url trực tiếp, tốt cũ 'indexOf ('/ api /')> -1' cũng nên hoạt động – Tukkan

+0

Câu trả lời này chỉ hoạt động nếu api còn lại được đặt tên tốt bằng cách sử dụng '/ api /'. Tôi thích kiểm tra tiêu đề http cho kiểu nội dung (chẳng hạn như XML hoặc JSON) – Yacine

0
/**object single interceptor**/ 
function SingleCallInterceptor(callbacks){ 

    this.receive=function(response) { 

     switch (response.status) { 

     case 200: 

      callbacks.success(apiResponse); 

      break; 

     default : 

      callbacks.error(response); 
     } 

    } 

    } 


var successfn=function(response){ //i have my response} 

var errorfn=function(response){ //i have my error} 

var responseInterceptor=new SingleCallInterceptor({success:successfn,error:errorfn}); 

     $http({ 

     url: "www.itsdirtysolutioniknow.it, 

     method: "GET", 

     dataType: "JSONP", 

     }).then(responseInterceptor.receive,responseInterceptor.receive); 
+0

Tính năng này chỉ cung cấp chức năng gọi lại. Làm thế nào người ta có thể sử dụng nó như một kẻ đánh chặn cuộc gọi http? –

0

cách ưa thích của tôi là sử dụng một đánh chặn HTTP thay thế một "kỳ diệu" tiêu đề Authorization với mã thông báo OAuth hiện tại. Mã dưới đây là OAuth cụ thể, nhưng khắc phục đó là một bài tập đơn giản cho người đọc.

// Injects an HTTP interceptor that replaces a "Bearer" authorization header 
// with the current Bearer token. 
module.factory('oauthHttpInterceptor', function (OAuth) { 
    return { 
    request: function (config) { 
     if (config.headers.Authorization === 'Bearer') { 
     config.headers.Authorization = 'Bearer ' + btoa(OAuth.accessToken); 
     } 
     return config; 
    } 
    }; 
}); 

module.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('oauthHttpInterceptor'); 
}); 
+1

Điều này không thực sự trả lời câu hỏi đã được yêu cầu – Squiggle

+0

Nó - chỉ cung cấp tiêu đề 'Authorization' của" Bearer "/" magic string "với yêu cầu của bạn (và không có người khác) và trình chặn sẽ được gọi. Bạn có thể sử dụng câu trả lời được chấp nhận - và điều này có lẽ rõ ràng hơn - nhưng sẽ có nghĩa là bạn đang ép buộc kẻ đánh chặn đó ở khắp mọi nơi - trong khi phương pháp trong ví dụ của tôi cung cấp sự vô hướng. –

0

Theo góc mặc định sẽ gửi và nhận tiêu đề ứng dụng/json. Bạn có thể có được điều này vào tiêu đề HTTP response như:

services.config(['$httpProvider',function($httpProvider) { 
    $httpProvider.interceptors.push('myHttpInterceptor'); 
}]); 

services.factory("userPurchased", function ($resource) { 
    return $resource("/api/user/purchases/:action/:item", 
     {}, 
     { 
      'list': {method: 'GET', params: {action: 'list'}, isArray: false}, 
      'save': {method: 'PUT', params: {item: '@item'}}, 
      'remove': {method: 'DELETE', params: {item: '@item'}}, 
     } 
    ); 
}); 

services.factory('myHttpInterceptor', function($q,$rootScope) { 
    // $rootScope.showSpinner = false; 
    return { 

     response: function(response) { 
     // use this line to if you are receiving json, else use xml or any other type 
     var isJson = response.config.headers.Accept.indexOf('json')>-1; 
     $rootScope.showSpinner = false; 
     // do something on success 
     console.log('success'); 
     console.log('status', response.status); 
     //return response; 
     return response || $q.when(response); 
     }, 

    responseError: function(response) { 
     // use this line to if you are receiving json, else use xml or any other type 
     var isJson = response.config.headers.Accept.indexOf('json')>-1; 
     // do something on error 
     $rootScope.showSpinner = true; 
     console.log('failure'); 
     console.log('status', response.status) 
     //return response; 
     return $q.reject(response); 
     } 
    }; 
    }); 
0

Tôi vừa bắt gặp một vấn đề mà cũng googleapis sử dụng một tiêu đề Authorization, và được ném một phản ứng 401 vì JWT tôi sử dụng trên máy chủ của tôi không hợp lệ cho máy chủ của họ (hiển nhiên) và mã của tôi được đặt để tự động xóa mã thông báo của tôi và chuyển hướng người đó đến trang đăng nhập. (Nó không được viết siêu tốt, vì BẤT CỨ 401 phản hồi sẽ đăng xuất người dùng của tôi).

Tôi chỉ đưa ra giải pháp này trong phương pháp request tôi trong đánh chặn, mà tôi nghĩ rằng tác phẩm khá tốt:

.service('authInterceptor', ["$q", "$location", "tokenService", function($q, $location, tokenService){ 
    this.request = function(config) { 
//  console.log($location.host()); 
     var token = tokenService.getToken(); 
     if(token && config.url.indexOf($location.host()) > -1) { 
      config.headers = config.headers || {}; 
      config.headers.Authorization = "Bearer " + token 
     } 
     return config 
    } 

    this.responseError = function(response) { 
//  console.log(response.config.url) 
     if (response.status === 401) { 
      tokenService.removeToken(); 
      $location.path('/login') 
     } 
     return $q.reject(response); 
    } 
}]) 

Các request kiểm tra phương pháp nếu tôi có một thẻ trong lưu trữ địa phương nếu url yêu cầu đang được thực hiện cho cùng một máy chủ (mà tôi nhận được từ $location.host()) làm một trang của tôi đang được phân phát trên. Điều này làm việc cho localhost cũng như bất kỳ URL nào tôi kết thúc việc triển khai trang web của mình.

Tôi đã không làm nhiều thử nghiệm với điều này, vì vậy nếu có ai tìm thấy một lỗ hổng trong việc này xin vui lòng cho tôi biết :)

Các vấn đề liên quan