aboutsummaryrefslogtreecommitdiffstats
path: root/src/service/http.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/http.js')
-rw-r--r--src/service/http.js322
1 files changed, 294 insertions, 28 deletions
diff --git a/src/service/http.js b/src/service/http.js
index e9c49ec2..f9a8d921 100644
--- a/src/service/http.js
+++ b/src/service/http.js
@@ -139,35 +139,314 @@ function $HttpProvider() {
* @requires $q
* @requires $injector
*
- * @param {object} config Object describing the request to be made and how it should be processed.
- * The object has following properties:
+ * @description
+ * The `$http` service is a core Angular service that is responsible for communication with the
+ * remote HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest
+ * XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
+ *
+ * For unit testing applications that use `$http` service, see
+ * {@link angular.module.ngMock.$httpBackend $httpBackend mock}.
+ *
+ * For a higher level of abstraction, please check out the {@link angular.module.ng.$resource
+ * $resource} service.
+ *
+ *
+ * # 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 {@link angular.module.ng.$q promise}
+ * with two $http specific methods: `success` and `error`.
+ *
+ * <pre>
+ * $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 status
+ * // code outside of the <200, 400) range
+ * });
+ * </pre>
+ *
+ * Since the returned value is a Promise object, 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.
+ *
+ *
+ * # Shortcut methods
+ *
+ * Since all invocation of the $http service require definition of the http method and url and
+ * POST and PUT requests require response body/data to be provided as well, shortcut methods
+ * were created to simplify using the api:
+ *
+ * <pre>
+ * $http.get('/someUrl').success(successCallback);
+ * $http.post('/someUrl', data).success(successCallback);
+ * </pre>
+ *
+ * Complete list of shortcut methods:
+ *
+ * - {@link angular.module.ng.$http#get $http.get}
+ * - {@link angular.module.ng.$http#head $http.head}
+ * - {@link angular.module.ng.$http#post $http.post}
+ * - {@link angular.module.ng.$http#put $http.put}
+ * - {@link angular.module.ng.$http#delete $http.delete}
+ * - {@link angular.module.ng.$http#jsonp $http.jsonp}
+ *
+ *
+ * # 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, * / *`
+ * - `X-Requested-With: XMLHttpRequest`
+ * - `$httpProvider.defaults.headers.post: (header defaults for HTTP POST requests)
+ * - `Content-Type: application/json`
+ * - `$httpProvider.defaults.headers.put` (header defaults for HTTP PUT requests)
+ * - `Content-Type: application/json`
+ *
+ * To add or overwrite these defaults, simply add or remove a property from this configuration
+ * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
+ * with name equal to the lower-cased http method name, e.g.
+ * `$httpProvider.defaults.headers.get['My-Header']='value'`.
+ *
+ *
+ * # Request / Response transformations
+ *
+ * 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 config 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
+ *
+ * These transformations can be overridden locally by specifying transform functions as
+ * `transformRequest` and/or `transformResponse` properties of the config object. To globally
+ * override the default transforms, override the `$httpProvider.defaults.transformRequest` and
+ * `$httpProvider.defaults.transformResponse` properties of the `$httpProvider`.
+ *
+ *
+ * # Caching
+ *
+ * You can enable caching by setting 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 for the first request.
+ *
+ *
+ * # Response interceptors
+ *
+ * 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 {@link angular.module.ng.$q
+ * 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 {@link angular.module.ng.$q promise} and returns the original or a new promise.
+ *
+ * Before you start creating interceptors, be sure to understand the
+ * {@link angular.module.ng.$q $q and deferred/promise APIs}.
+ *
+ * <pre>
+ * // 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
+ * }, 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
+ * }
+ * });
+ * </pre>
+ *
+ *
+ * # Security Considerations
+ *
+ * When designing web applications your design needs to consider security threats from
+ * {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
+ * JSON Vulnerability} and {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}.
+ * 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 {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
+ * JSON Vulnerability} allows third party web-site to turn your JSON resource URL into
+ * {@link http://en.wikipedia.org/wiki/JSON#JSONP 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:
+ * <pre>
+ * ['one','two']
+ * </pre>
+ *
+ * which is vulnerable to attack, your server can return:
+ * <pre>
+ * )]}',
+ * ['one','two']
+ * </pre>
+ *
+ * Angular will strip the prefix, before processing the JSON.
+ *
+ *
+ * ## Cross Site Request Forgery (XSRF) Protection
+ *
+ * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
+ * an unauthorized site can gain your user's private data. Angular provides following mechanism
+ * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
+ * called `XSRF-TOKEN` and sets it as the 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.
+ *
+ * To take advantage of this, your server needs to set a token in a JavaScript readable session
+ * cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET 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 read the token. The token must be
+ * unique for each user and must be verifiable by the server (to prevent the JavaScript making
+ * up its own tokens). We recommend that the token is a digest of your site's authentication
+ * cookie with {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
+ *
+ *
+ * @param {object} config 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.
* - **data** – `{string|Object}` – Data to be sent as the request message data.
* - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
+ * - **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.
+ * GET request, otherwise if a cache instance built with
+ * {@link angular.module.ng.$cacheFactory $cacheFactory}, this cache will be used for
+ * caching.
+ * - **timeout** – `{number}` – timeout in milliseconds.
*
- * @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:
+ * @returns {HttpPromise} Returns a {@link angular.module.ng.$q 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.
*
- * @property {Array.<Object>} pendingRequests Array of config objects for pending requests.
- * This is primarily meant to be used for debugging purposes.
+ * @property {Array.<Object>} pendingRequests Array of config objects for currently pending
+ * requests. This is primarily meant to be used for debugging purposes.
*
- * @description
- * $http is a service through which XHR and JSONP requests can be made.
+ *
+ * @example
+ <doc:example>
+ <doc:source jsfiddle="false">
+ <script>
+ function FetchCtrl($http) {
+ var self = this;
+ this.method = 'GET';
+ this.url = 'examples/http-hello.html';
+
+ this.fetch = function() {
+ self.code = null;
+ self.response = null;
+
+ $http({method: self.method, url: self.url}).
+ success(function(data, status) {
+ self.status = status;
+ self.data = data;
+ }).
+ error(function(data, status) {
+ self.data = data || "Request failed";
+ self.status = status;
+ });
+ };
+
+ this.updateModel = function(method, url) {
+ self.method = method;
+ self.url = url;
+ };
+ }
+ </script>
+ <div ng:controller="FetchCtrl">
+ <select ng:model="method">
+ <option>GET</option>
+ <option>JSONP</option>
+ </select>
+ <input type="text" ng:model="url" size="80"/>
+ <button ng:click="fetch()">fetch</button><br>
+ <button ng:click="updateModel('GET', 'examples/http-hello.html')">Sample GET</button>
+ <button ng:click="updateModel('JSONP', 'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">Sample JSONP</button>
+ <button 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>
+ </doc:source>
+ <doc:scenario>
+ it('should make an xhr GET request', function() {
+ element(':button:contains("Sample GET")').click();
+ element(':button:contains("fetch")').click();
+ expect(binding('status')).toBe('http status code: 200');
+ expect(binding('data')).toBe('http response data: Hello, $http!\n');
+ });
+
+ it('should make a JSONP request to angularjs.org', function() {
+ element(':button:contains("Sample JSONP")').click();
+ element(':button:contains("fetch")').click();
+ expect(binding('status')).toBe('http status code: 200');
+ expect(binding('data')).toMatch(/Super Hero!/);
+ });
+
+ it('should make JSONP request to invalid URL and invoke the error handler',
+ function() {
+ element(':button:contains("Invalid JSONP")').click();
+ element(':button:contains("fetch")').click();
+ expect(binding('status')).toBe('http status code: 0');
+ expect(binding('data')).toBe('http response data: Request failed');
+ });
+ </doc:scenario>
+ </doc:example>
*/
function $http(config) {
config.method = uppercase(config.method);
@@ -263,19 +542,6 @@ function $HttpProvider() {
/**
* @ngdoc method
- * @name angular.module.ng.$http#patch
- * @methodOf angular.module.ng.$http
- *
- * @description
- * Shortcut method to perform `PATCH` request
- *
- * @param {string} url Relative or absolute URL specifying the destination of the request
- * @param {Object=} config Optional configuration object
- * @returns {HttpPromise} Future object
- */
-
- /**
- * @ngdoc method
* @name angular.module.ng.$http#jsonp
* @methodOf angular.module.ng.$http
*