Improve this doc  View Source

$http

  1. - service in module ng

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.

Writing Unit Tests that use $http

When unit testing (using ngMock), it is necessary to call $httpBackend.flush() to flush each pending request using trained responses.

$httpBackend.expectGET(...);
$http.get(...);
$httpBackend.flush();

Shortcut methods

Shortcut methods are also available. All shortcut methods require passing in the URL, and request data must be passed in for POST/PUT requests.

  $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:

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' }.

The defaults can also be set at runtime via the $http.defaults object in the same fashion. For example:

module.run(function($http) {
  $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'
});

In addition, you can supply a headers property in the config object passed when calling $http(config), which overrides the defaults without changing them globally.

Transforming Requests and Responses

Both requests and responses can be transformed using transform functions. By default, Angular applies these transformations:

Request transformations:

Response transformations:

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. These defaults are again available on the $http factory at run-time, which may be useful if you have run-time services you wish to be involved in your transformations.

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 request configuration cache property to true (to use default cache) or to a custom cache object (built with $cacheFactory). When the cache is enabled, $http stores the response from the server in the specified cache. The next time the same request is made, 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.

You can change the default cache to a new object (built with $cacheFactory) by updating the $http.defaults.cache property. All requests who set their cache property to true will now use this cache object.

If you set the default cache to false then only requests that specify their own custom cache object will be cached.

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):

  // 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');


  // alternatively, 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 at config-time, $http.defaults at run-time, or the per-request config object.

Dependencies

Usage

$http(config);

Arguments

Param Type Details
config object

Object describing the request to be made and how it should be processed. The object has following properties:

  • method{string} – HTTP method (e.g. 'GET', 'POST', etc)
  • url{string} – Absolute or relative URL of the resource that is being requested.
  • params{Object.<string|Object>} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.
  • data{string|Object} – Data to be sent as the request message data.
  • headers{Object} – Map of strings or functions which return strings representing HTTP headers to send to the server. If the return value of a function is null, the header will not be sent.
  • xsrfHeaderName{string} – Name of HTTP header to populate with the XSRF token.
  • xsrfCookieName{string} – Name of cookie containing the XSRF token.
  • transformRequest{function(data, headersGetter)|Array.<function(data, headersGetter)>} – transform function or an array of such functions. The transform function takes the http request body and headers and returns its transformed (typically serialized) version.
  • transformResponse{function(data, headersGetter)|Array.<function(data, headersGetter)>} – transform function or an array of such functions. The transform function takes the http response body and headers and returns its transformed (typically deserialized) version.
  • cache{boolean|Cache} – If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching.
  • timeout{number|Promise} – timeout in milliseconds, or promise that should abort the request when resolved.
  • withCredentials - {boolean} - whether to to set the withCredentials flag on the XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5 for more information.
  • responseType - {string} - see requestType.

Returns

HttpPromise

Returns a promise object with the standard then method and two http specific methods: success and error. The then method takes two arguments a success and an error callback which will be called with a response object. The success and error methods take a single argument - a function that will be called when the request succeeds or fails respectively. The arguments passed into these functions are destructured representation of the response object passed into the then method. The response object has these properties:

  • data{string|Object} – The response body transformed with the transform functions.
  • status{number} – HTTP status code of the response.
  • headers{function([headerName])} – Header getter function.
  • config{Object} – The configuration object that was used to generate the request.
  • statusText{string} – HTTP status text of the response.

Methods

Properties

Example

  Edit in Plunker
<div ng-controller="FetchCtrl">
<select ng-model="method">
  <option>GET</option>
  <option>JSONP</option>
</select>
<input type="text" ng-model="url" size="80"/>
<button id="fetchbtn" ng-click="fetch()">fetch</button><br>
<button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
<button id="samplejsonpbtn"
  ng-click="updateModel('JSONP',
                'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
  Sample JSONP
</button>
<button id="invalidjsonpbtn"
  ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
    Invalid JSONP
  </button>
<pre>http status code: {{status}}</pre>
<pre>http response data: {{data}}</pre>
</div>
function FetchCtrl($scope, $http, $templateCache) {
$scope.method = 'GET';
$scope.url = 'http-hello.html';

$scope.fetch = function() {
  $scope.code = null;
  $scope.response = null;

  $http({method: $scope.method, url: $scope.url, cache: $templateCache}).
    success(function(data, status) {
      $scope.status = status;
      $scope.data = data;
    }).
    error(function(data, status) {
      $scope.data = data || "Request failed";
      $scope.status = status;
  });
};

$scope.updateModel = function(method, url) {
  $scope.method = method;
  $scope.url = url;
};
}
Hello, $http!
var status = element(by.binding('status'));
var data = element(by.binding('data'));
var fetchBtn = element(by.id('fetchbtn'));
var sampleGetBtn = element(by.id('samplegetbtn'));
var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));

it('should make an xhr GET request', function() {
  sampleGetBtn.click();
  fetchBtn.click();
  expect(status.getText()).toMatch('200');
  expect(data.getText()).toMatch(/Hello, \$http!/);
});

it('should make a JSONP request to angularjs.org', function() {
  sampleJsonpBtn.click();
  fetchBtn.click();
  expect(status.getText()).toMatch('200');
  expect(data.getText()).toMatch(/Super Hero!/);
});

it('should make JSONP request to invalid URL and invoke the error handler',
    function() {
  invalidJsonpBtn.click();
  fetchBtn.click();
  expect(status.getText()).toMatch('0');
  expect(data.getText()).toMatch('Request failed');
});