The $http
service is a core Angular service that facilitates communication with the remote
HTTP servers via the browser's XMLHttpRequest object or via JSONP.
For unit testing applications that use $http
service, see
$httpBackend mock.
For a higher level of abstraction, please check out the $resource service.
The $http API is based on the deferred/promise APIs
exposed by
the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
it is important to familiarize yourself with these APIs and the guarantees they provide.
General usage
The $http
service is a function which takes a single argument — a configuration object —
that is used to generate an HTTP request and returns a promise
with two $http specific methods: success
and error
.
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Since the returned value of calling the $http function is a promise
, you can also use
the then
method to register callbacks, and these callbacks will receive a single argument –
an object representing the response. See the API signature and type info below for more
details.
A response status code between 200 and 299 is considered a success status and
will result in the success callback being called. Note that if the response is a redirect,
XMLHttpRequest will transparently follow it, meaning that the error callback will not be
called for such responses.
Shortcut methods
Since all invocations of the $http service require passing in an HTTP method and URL, and
POST/PUT requests require request data to be provided as well, shortcut methods
were created:
$http.get('/someUrl').success(successCallback);
$http.post('/someUrl', data).success(successCallback);
Complete list of shortcut methods:
Setting HTTP Headers
The $http service will automatically add certain HTTP headers to all requests. These defaults
can be fully configured by accessing the $httpProvider.defaults.headers
configuration
object, which currently contains this default configuration:
$httpProvider.defaults.headers.common
(headers that are common for all requests):
Accept: application/json, text/plain, * / *
$httpProvider.defaults.headers.post
: (header defaults for POST requests)
Content-Type: application/json
$httpProvider.defaults.headers.put
(header defaults for PUT requests)
Content-Type: application/json
To add or overwrite these defaults, simply add or remove a property from these configuration
objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
with the lowercased HTTP method name as the key, e.g.
$httpProvider.defaults.headers.get['My-Header']='value'
.
Additionally, the defaults can be set at runtime via the $http.defaults
object in the same
fashion.
Transforming Requests and Responses
Both requests and responses can be transformed using transform functions. By default, Angular
applies these transformations:
Request transformations:
- If the
data
property of the request configuration object contains an object, serialize it into
JSON format.
Response transformations:
- If XSRF prefix is detected, strip it (see Security Considerations section below).
- If JSON response is detected, deserialize it using a JSON parser.
To globally augment or override the default transforms, modify the $httpProvider.defaults.transformRequest
and
$httpProvider.defaults.transformResponse
properties. These properties are by default an
array of transform functions, which allows you to push
or unshift
a new transformation function into the
transformation chain. You can also decide to completely override any default transformations by assigning your
transformation functions to these properties directly without the array wrapper.
Similarly, to locally override the request/response transforms, augment the transformRequest
and/or
transformResponse
properties of the configuration object passed into $http
.
Caching
To enable caching, set the configuration property cache
to true
. When the cache is
enabled, $http
stores the response from the server in local cache. Next time the
response is served from the cache without sending a request to the server.
Note that even if the response is served from cache, delivery of the data is asynchronous in
the same way that real requests are.
If there are multiple GET requests for the same URL that should be cached using the same
cache, but the cache is not populated yet, only one request to the server will be made and
the remaining requests will be fulfilled using the response from the first request.
A custom default cache built with $cacheFactory can be provided in $http.defaults.cache.
To skip it, set configuration property cache
to false
.
Interceptors
Before you start creating interceptors, be sure to understand the
$q and deferred/promise APIs
.
For purposes of global error handling, authentication, or any kind of synchronous or
asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
able to intercept requests before they are handed to the server and
responses before they are handed over to the application code that
initiated these requests. The interceptors leverage the promise APIs
to fulfill this need for both synchronous and asynchronous pre-processing.
The interceptors are service factories that are registered with the $httpProvider
by
adding them to the $httpProvider.interceptors
array. The factory is called and
injected with dependencies (if specified) and returns the interceptor.
There are two kinds of interceptors (and two kinds of rejection interceptors):
request
: interceptors get called with http config
object. The function is free to modify
the config
or create a new one. The function needs to return the config
directly or as a
promise.
requestError
: interceptor gets called when a previous interceptor threw an error or resolved
with a rejection.
response
: interceptors get called with http response
object. The function is free to modify
the response
or create a new one. The function needs to return the response
directly or as a
promise.
responseError
: interceptor gets called when a previous interceptor threw an error or resolved
with a rejection.
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return {
// optional method
'request': function(config) {
// do something on success
return config || $q.when(config);
},
// optional method
'requestError': function(rejection) {
// do something on error
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
return response || $q.when(response);
},
// optional method
'responseError': function(rejection) {
// do something on error
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
};
}
});
$httpProvider.interceptors.push('myHttpInterceptor');
// register the interceptor via an anonymous factory
$httpProvider.interceptors.push(function($q, dependency1, dependency2) {
return {
'request': function(config) {
// same as above
},
'response': function(response) {
// same as above
}
});
Response interceptors (DEPRECATED)
Before you start creating interceptors, be sure to understand the
$q and deferred/promise APIs
.
For purposes of global error handling, authentication or any kind of synchronous or
asynchronous preprocessing of received responses, it is desirable to be able to intercept
responses for http requests before they are handed over to the application code that
initiated these requests. The response interceptors leverage the promise apis
to fulfil this need for both synchronous and asynchronous preprocessing.
The interceptors are service factories that are registered with the $httpProvider by
adding them to the $httpProvider.responseInterceptors
array. The factory is called and
injected with dependencies (if specified) and returns the interceptor — a function that
takes a promise
and returns the original or a new promise.
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return function(promise) {
return promise.then(function(response) {
// do something on success
return response;
}, function(response) {
// do something on error
if (canRecover(response)) {
return responseOrNewPromise
}
return $q.reject(response);
});
}
});
$httpProvider.responseInterceptors.push('myHttpInterceptor');
// register the interceptor via an anonymous factory
$httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) {
return function(promise) {
// same as above
}
});
Security Considerations
When designing web applications, consider security threats from:
Both server and the client must cooperate in order to eliminate these threats. Angular comes
pre-configured with strategies that address these issues, but for this to work backend server
cooperation is required.
JSON Vulnerability Protection
A JSON vulnerability allows third party website to turn your JSON resource URL into
JSONP request under some conditions. To
counter this your server can prefix all JSON requests with following string ")]}',\n"
.
Angular will automatically strip the prefix before processing it as JSON.
For example if your server needs to return:
['one','two']
which is vulnerable to attack, your server can return:
)]}',
['one','two']
Angular will strip the prefix, before processing the JSON.
Cross Site Request Forgery (XSRF) Protection
XSRF is a technique by which
an unauthorized site can gain your user's private data. Angular provides a mechanism
to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
(by default, XSRF-TOKEN
) and sets it as an HTTP header (X-XSRF-TOKEN
). Since only
JavaScript that runs on your domain could read the cookie, your server can be assured that
the XHR came from JavaScript running on your domain. The header will not be set for
cross-domain requests.
To take advantage of this, your server needs to set a token in a JavaScript readable session
cookie called XSRF-TOKEN
on the first HTTP GET request. On subsequent XHR requests the
server can verify that the cookie matches X-XSRF-TOKEN
HTTP header, and therefore be sure
that only JavaScript running on your domain could have sent the request. The token must be
unique for each user and must be verifiable by the server (to prevent the JavaScript from making
up its own tokens). We recommend that the token is a digest of your site's authentication
cookie with a salt for added security.
The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName
properties of either $httpProvider.defaults, or the per-request config object.