mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
docs($http, $httpBackend): docs docs docs
This commit is contained in:
parent
d2ba4c5170
commit
939c8e8fac
4 changed files with 869 additions and 35 deletions
1
docs/examples/http-hello.html
Normal file
1
docs/examples/http-hello.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
Hello, $http!
|
||||
576
src/angular-mocks.js
vendored
576
src/angular-mocks.js
vendored
|
|
@ -580,11 +580,175 @@ angular.mock.dump = function(object) {
|
|||
/**
|
||||
* @ngdoc object
|
||||
* @name angular.module.ngMock.$httpBackend
|
||||
* @describe
|
||||
* Fake version of `$httpBackend` service used by the `$http` service during unit testing.
|
||||
* @description
|
||||
* Fake HTTP backend implementation suitable for unit testing application that use the
|
||||
* {@link angular.module.ng.$http $http service}.
|
||||
*
|
||||
* This implementation can be used to respond with static or dynamic responses via the `expect` and
|
||||
* `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
|
||||
* *Note*: For fake http backend implementation suitable for end-to-end testing or backend-less
|
||||
* development please see {@link angular.module.ngMockE2E.$httpBackend e2e $httpBackend mock}.
|
||||
*
|
||||
* During unit testing, we want our unit tests to run quickly and have no external dependencies so
|
||||
* we don’t want to send {@link https://developer.mozilla.org/en/xmlhttprequest XHR} or
|
||||
* {@link http://en.wikipedia.org/wiki/JSONP JSONP} requests to a real server. All we really need is
|
||||
* to verify whether a certain request has been sent or not, or alternatively just let the
|
||||
* application make requests, respond with pre-trained responses and assert that the end result is
|
||||
* what we expect it to be.
|
||||
*
|
||||
* This mock implementation can be used to respond with static or dynamic responses via the
|
||||
* `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
|
||||
*
|
||||
* When an Angular application needs some data from a server, it calls the $http service, which
|
||||
* sends the request to a real server using $httpBackend service. With dependency injection, it is
|
||||
* easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify
|
||||
* the requests and respond with some testing data without sending a request to real server.
|
||||
*
|
||||
* There are two ways to specify what test data should be returned as http responses by the mock
|
||||
* backend when the code under test makes http requests:
|
||||
*
|
||||
* - `$httpBackend.expect` - specifies a request expectation
|
||||
* - `$httpBackend.when` - specifies a backend definition
|
||||
*
|
||||
*
|
||||
* # Request Expectations vs Backend Definitions
|
||||
*
|
||||
* Request expectations provide a way to make assertions about requests made by the application and
|
||||
* to define responses for those requests. The test will fail if the expected requests are not made
|
||||
* or they are made in the wrong order.
|
||||
*
|
||||
* Backend definitions allow you to define a fake backend for your application which doesn't assert
|
||||
* if a particular request was made or not, it just returns a trained response if a request is made.
|
||||
* The test will pass whether or not the request gets made during testing.
|
||||
*
|
||||
*
|
||||
* <table class="table">
|
||||
* <tr><th width="220px"></th><th>Request expectations</th><th>Backend definitions</th></tr>
|
||||
* <tr>
|
||||
* <th>Syntax</th>
|
||||
* <td>.expect(...).respond(...)</td>
|
||||
* <td>.when(...).respond(...)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Typical usage</th>
|
||||
* <td>strict unit tests</td>
|
||||
* <td>loose (black-box) unit testing</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Fulfills multiple requests</th>
|
||||
* <td>NO</td>
|
||||
* <td>YES</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Order of requests matters</th>
|
||||
* <td>YES</td>
|
||||
* <td>NO</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Request required</th>
|
||||
* <td>YES</td>
|
||||
* <td>NO</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th>Response required</th>
|
||||
* <td>optional (see below)</td>
|
||||
* <td>YES</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* In cases where both backend definitions and request expectations are specified during unit
|
||||
* testing, the request expectations are evaluated first.
|
||||
*
|
||||
* If a request expectation has no response specified, the algorithm will search your backend
|
||||
* definitions for an appropriate response.
|
||||
*
|
||||
* If a request didn't match any expectation or if the expectation doesn't have the response
|
||||
* defined, the backend definitions are evaluated in sequential order to see if any of them match
|
||||
* the request. The response from the first matched definition is returned.
|
||||
*
|
||||
*
|
||||
* # Flushing HTTP requests
|
||||
*
|
||||
* The $httpBackend used in production, always responds to requests with responses asynchronously.
|
||||
* If we preserved this behavior in unit testing, we'd have to create async unit tests, which are
|
||||
* hard to write, follow and maintain. At the same time the testing mock, can't respond
|
||||
* synchronously because that would change the execution of the code under test. For this reason the
|
||||
* mock $httpBackend has a `flush()` method, which allows the test to explicitly flush pending
|
||||
* requests and thus preserving the async api of the backend, while allowing the test to execute
|
||||
* synchronously.
|
||||
*
|
||||
*
|
||||
* # Unit testing with mock $httpBackend
|
||||
*
|
||||
* <pre>
|
||||
// controller
|
||||
function MyController($http) {
|
||||
var scope = this;
|
||||
|
||||
$http.get('/auth.py').success(function(data) {
|
||||
scope.user = data;
|
||||
});
|
||||
|
||||
this.saveMessage = function(message) {
|
||||
scope.status = 'Saving...';
|
||||
$http.post('/add-msg.py', message).success(function(response) {
|
||||
scope.status = '';
|
||||
}).error(function() {
|
||||
scope.status = 'ERROR!';
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// testing controller
|
||||
var $http;
|
||||
|
||||
beforeEach(inject(function($injector) {
|
||||
$httpBackend = $injector.get('$httpBackend');
|
||||
|
||||
// backend definition common for all tests
|
||||
$httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'});
|
||||
}));
|
||||
|
||||
|
||||
afterEach(function() {
|
||||
$httpBackend.verifyNoOutstandingExpectation();
|
||||
$httpBackend.verifyNoOutstandingRequest();
|
||||
});
|
||||
|
||||
|
||||
it('should fetch authentication token', function() {
|
||||
$httpBackend.expectGET('/auth.py');
|
||||
var controller = scope.$new(MyController);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
||||
|
||||
it('should send msg to server', function() {
|
||||
// now you don’t care about the authentication, but
|
||||
// the controller will still send the request and
|
||||
// $httpBackend will respond without you having to
|
||||
// specify the expectation and response for this request
|
||||
$httpBackend.expectPOST('/add-msg.py', 'message content').respond(201, '');
|
||||
|
||||
var controller = scope.$new(MyController);
|
||||
$httpBackend.flush();
|
||||
controller.saveMessage('message content');
|
||||
expect(controller.status).toBe('Saving...');
|
||||
$httpBackend.flush();
|
||||
expect(controller.status).toBe('');
|
||||
});
|
||||
|
||||
|
||||
it('should send auth header', function() {
|
||||
$httpBackend.expectPOST('/add-msg.py', undefined, function(headers) {
|
||||
// check if the header was send, if it wasn't the expectation won't
|
||||
// match the request and the test will fail
|
||||
return headers['Authorization'] == 'xxx';
|
||||
}).respond(201, '');
|
||||
|
||||
var controller = scope.$new(MyController);
|
||||
controller.saveMessage('whatever');
|
||||
$httpBackend.flush();
|
||||
});
|
||||
</pre>
|
||||
*/
|
||||
angular.mock.$HttpBackendProvider = function() {
|
||||
this.$get = [createHttpBackendMock];
|
||||
|
|
@ -677,6 +841,26 @@ function createHttpBackendMock($delegate, $defer) {
|
|||
(expectation ? 'Expected ' + expectation : 'No more request expected'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#when
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition.
|
||||
*
|
||||
* @param {string} method HTTP method.
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
||||
* object and returns true if the headers match the current definition.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*
|
||||
* - respond – `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
||||
* – The respond method takes a set of static data to be returned or a function that can return
|
||||
* an array containing response status (number), response data (string) and response headers
|
||||
* (Object).
|
||||
*/
|
||||
$httpBackend.when = function(method, url, data, headers) {
|
||||
var definition = new MockHttpExpectation(method, url, data, headers),
|
||||
chain = {
|
||||
|
|
@ -695,9 +879,107 @@ function createHttpBackendMock($delegate, $defer) {
|
|||
return chain;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#whenGET
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for GET requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#whenHEAD
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for HEAD requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#whenDELETE
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for DELETE requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#whenPOST
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for POST requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#whenPUT
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for PUT requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#whenJSONP
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for JSONP requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
createShortMethods('when');
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expect
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation.
|
||||
*
|
||||
* @param {string} method HTTP method.
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
||||
* object and returns true if the headers match the current expectation.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*
|
||||
* - respond – `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
||||
* – The respond method takes a set of static data to be returned or a function that can return
|
||||
* an array containing response status (number), response data (string) and response headers
|
||||
* (Object).
|
||||
*/
|
||||
$httpBackend.expect = function(method, url, data, headers) {
|
||||
var expectation = new MockHttpExpectation(method, url, data, headers);
|
||||
expectations.push(expectation);
|
||||
|
|
@ -708,9 +990,99 @@ function createHttpBackendMock($delegate, $defer) {
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expectGET
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation for GET requests. For more info see `expect()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled. See #expect for more info.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expectHEAD
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation for HEAD requests. For more info see `expect()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expectDELETE
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation for DELETE requests. For more info see `expect()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expectPOST
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation for POST requests. For more info see `expect()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expectPUT
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation for PUT requests. For more info see `expect()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#expectJSONP
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Creates a new request expectation for JSONP requests. For more info see `expect()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* request is handled.
|
||||
*/
|
||||
createShortMethods('expect');
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#flush
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Flushes all pending requests using the trained responses.
|
||||
*
|
||||
* @param {number=} count Number of responses to flush (in the order they arrived). If undefined,
|
||||
* all pending requests will be flushed. If there are no pending requests when the flush method
|
||||
* is called an exception is thrown (as this typically a sign of programming error).
|
||||
*/
|
||||
$httpBackend.flush = function(count) {
|
||||
if (!responses.length) throw Error('No pending request to flush !');
|
||||
|
||||
|
|
@ -727,18 +1099,59 @@ function createHttpBackendMock($delegate, $defer) {
|
|||
$httpBackend.verifyNoOutstandingExpectation();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#verifyNoOutstandingExpectation
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Verifies that all of the requests defined via the `expect` api were made. If any of the
|
||||
* requests were not made, verifyNoOutstandingExpectation throws an exception.
|
||||
*
|
||||
* Typically, you would call this method following each test case that asserts requests using an
|
||||
* "afterEach" clause.
|
||||
*
|
||||
* <pre>
|
||||
* afterEach($httpBackend.verifyExpectations);
|
||||
* </pre>
|
||||
*/
|
||||
$httpBackend.verifyNoOutstandingExpectation = function() {
|
||||
if (expectations.length) {
|
||||
throw Error('Unsatisfied requests: ' + expectations.join(', '));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#verifyNoOutstandingRequest
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Verifies that there are no outstanding requests that need to be flushed.
|
||||
*
|
||||
* Typically, you would call this method following each test case that asserts requests using an
|
||||
* "afterEach" clause.
|
||||
*
|
||||
* <pre>
|
||||
* afterEach($httpBackend.verifyNoOutstandingRequest);
|
||||
* </pre>
|
||||
*/
|
||||
$httpBackend.verifyNoOutstandingRequest = function() {
|
||||
if (responses.length) {
|
||||
throw Error('Unflushed requests: ' + responses.length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMock.$httpBackend#resetExpectations
|
||||
* @methodOf angular.module.ngMock.$httpBackend
|
||||
* @description
|
||||
* Resets all request expectations, but preserves all backend definitions. Typically, you would
|
||||
* call resetExpectations during a multiple-phase test when you want to reuse the same instance of
|
||||
* $httpBackend mock.
|
||||
*/
|
||||
$httpBackend.resetExpectations = function() {
|
||||
expectations.length = 0;
|
||||
responses.length = 0;
|
||||
|
|
@ -870,13 +1283,164 @@ angular.module('ngMock', ['ng']).service({
|
|||
* @name angular.module.ngMockE2E
|
||||
* @description
|
||||
*
|
||||
* The `ngMockE2E` is an angular module which contains mock for `$httpBackend`. This mock allows you
|
||||
* to either respond with fake data or delegate to real backend.
|
||||
* The `ngMockE2E` is an angular module which contains mocks suitable for end-to-end testing.
|
||||
* Currently there is only one mock present in this module -
|
||||
* the {@link angular.module.ngMockE2E.$httpBackend e2e $httpBackend} mock.
|
||||
*/
|
||||
angular.module('ngMockE2E', ['ng']).init(function($provide) {
|
||||
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
|
||||
});
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Fake HTTP backend implementation suitable for end-to-end testing or backend-less development of
|
||||
* applications that use the {@link angular.module.ng.$http $http service}.
|
||||
*
|
||||
* *Note*: For fake http backend implementation suitable for unit testing please see
|
||||
* {@link angular.module.ngMock.$httpBackend unit-testing $httpBackend mock}.
|
||||
*
|
||||
* This implementation can be used to respond with static or dynamic responses via the `when` api
|
||||
* and its shortcuts (`whenGET`, `whenPOST`, etc) and optionally pass through requests to the
|
||||
* real $httpBackend for specific requests (e.g. to interact with certain remote apis or to fetch
|
||||
* templates from a webserver).
|
||||
*
|
||||
* As opposed to unit-testing, in an end-to-end testing scenario or in scenario when an application
|
||||
* is being developed with the real backend api replaced with a mock, it is often desirable for
|
||||
* certain category of requests to bypass the mock and issue a real http request (e.g. to fetch
|
||||
* templates or static files from the webserver). To configure the backend with this behavior
|
||||
* use the `passThrough` request handler of `when` instead of `respond`.
|
||||
*
|
||||
* Additionally, we don't want to manually have to flush mocked out requests like we do during unit
|
||||
* testing. For this reason the e2e $httpBackend automatically flushes mocked out requests
|
||||
* automatically, closely simulating the behavior of the XMLHttpRequest object.
|
||||
*
|
||||
* To setup the application to run with this http backend, you have to create a module that depends
|
||||
* on the `ngMockE2E` and your application modules and defines the fake backend:
|
||||
*
|
||||
* <pre>
|
||||
* myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']);
|
||||
* myAppDev.run(function($httpBackend) {
|
||||
* phones = [{name: 'phone1'}, {name: 'phone2'}];
|
||||
*
|
||||
* // returns the current list of phones
|
||||
* $httpBackend.whenGET('/phones').respond(phones);
|
||||
*
|
||||
* // adds a new phone to the phones array
|
||||
* $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
|
||||
* phones.push(angular.fromJSON(data));
|
||||
* });
|
||||
* $httpBackend.whenGET(/^\/templates\//).passThrough();
|
||||
* //...
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* Afterwards, bootstrap your app with this new module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#when
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition.
|
||||
*
|
||||
* @param {string} method HTTP method.
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
||||
* object and returns true if the headers match the current definition.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*
|
||||
* - respond – `{function([status,] data[, headers])|function(function(method, url, data, headers)}`
|
||||
* – The respond method takes a set of static data to be returned or a function that can return
|
||||
* an array containing response status (number), response data (string) and response headers
|
||||
* (Object).
|
||||
* - passThrough – `{function()}` – Any request matching a backend definition with `passThrough`
|
||||
* handler, will be pass through to the real backend (an XHR request will be made to the
|
||||
* server.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#whenGET
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for GET requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#whenHEAD
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for HEAD requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#whenDELETE
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for DELETE requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#whenPOST
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for POST requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#whenPUT
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for PUT requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @param {(string|RegExp)=} data HTTP request body.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name angular.module.ngMockE2E.$httpBackend#whenJSONP
|
||||
* @methodOf angular.module.ngMockE2E.$httpBackend
|
||||
* @description
|
||||
* Creates a new backend definition for JSONP requests. For more info see `when()`.
|
||||
*
|
||||
* @param {string|RegExp} url HTTP url.
|
||||
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
|
||||
* control how a matched request is handled.
|
||||
*/
|
||||
angular.mock.e2e = {};
|
||||
angular.mock.e2e.$httpBackendDecorator = ['$delegate', '$defer', createHttpBackendMock];
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -261,19 +540,6 @@ function $HttpProvider() {
|
|||
* @returns {XhrFuture} Future object
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
|
|||
|
|
@ -15,7 +15,10 @@ var XHR = window.XMLHttpRequest || function() {
|
|||
*
|
||||
* @description
|
||||
* HTTP backend used by the {@link angular.module.ng.$http service} that delegates to
|
||||
* XMLHttpRequest object.
|
||||
* XMLHttpRequest object or JSONP and deals with browser incompatibilities.
|
||||
*
|
||||
* You should never need to use this service directly, instead use the higher-level abstractions:
|
||||
* {@link angular.module.ng.$http $http} or {@link angular.module.ng.$resource $resource}.
|
||||
*
|
||||
* During testing this implementation is swapped with {@link angular.module.ngMock.$httpBackend mock
|
||||
* $httpBackend} which can be trained with responses.
|
||||
|
|
|
|||
Loading…
Reference in a new issue