angular/angular.js — pull request #1701 by inukshuk (2012-12-13 13:38:19+00:00)
Title: feat($http): promise-based request interceptors

Currently there is no easy way to globally intercept requests sent with $http – similar to the way responses can be intercepted with response interceptors. Furthermore, there are many legitimate scenarios and use-cases where the need for request interception arises; for example

* if security tokens, parameters or headers need to be calculated for each individual request
* for collecting statistics like request counts, measuring turnaround times etc.
* for dynamic, client-side redirects (e.g., rewrite /api/x to /api/experimental/x for resource x but not resource y)

Please see #929 for a further discussion (and use-cases) on this topic.

## Implementation

The request interceptor registration works exactly like the registration of response interceptors (in fact, I have put this into a separate routine to make it more explicit). If request interceptors are present, they are prepended to the promise chain returned by $http – this was mostly devised and written by @splondike – this gives the interceptors a lot of flexibility and fits very well into the Angular API.

## Tests and Documentation

This pull requests includes both tests and documentation of the new feature.

A note on testing: a separate call to $rootScope.$apply is necessary to test the interceptors with the mocked http backend.

## Example

// register interceptor using an anonymous function
$httpProvider.requestInterceptors.push(function() {
return function(promise) {
return promise.then(function(config) {

// the config object will be used by the actual request
// you can modify it here

config.url = '/intercepted/' + config.url;

// return the config object to pass it on to the next interceptor
return config;

// if you reject the promise, the promise
// returned by $http will be rejected
};
};
});

## Compatibility

When no request interceptors are registered, no promises are prepended to the chain. Therefore, this feature should be completely backwards compatible – if you register not interceptors everything stays the same.