3
3
* @ngdoc service
4
4
* @name angular.service.$xhr
5
5
* @function
6
- * @requires $browser
7
- * @requires $xhr.error
8
- * @requires $log
6
+ * @requires $browser $xhr delegates all XHR requests to the `$browser.xhr()`. A mock version
7
+ * of the $browser exists which allows setting expectaitions on XHR requests
8
+ * in your tests
9
+ * @requires $xhr.error $xhr delegates all non `2xx` response code to this service.
10
+ * @requires $log $xhr delegates all exceptions to `$log.error()`.
11
+ * @requires $updateView After a server response the view needs to be updated for data-binding to
12
+ * take effect.
9
13
*
10
14
* @description
11
- * Generates an XHR request. The $xhr service adds error handling then delegates all requests to
12
- * {@link angular.service.$browser $browser.xhr()}.
15
+ * Generates an XHR request. The $xhr service delegates all requests to
16
+ * {@link angular.service.$browser $browser.xhr()} and adds error handling and security features.
17
+ * While $xhr service provides nicer api than raw XmlHttpRequest, it is still considered a lower
18
+ * level api in angular. For a higher level abstraction that utilizes `$xhr`, please check out the
19
+ * {@link angular.service$resource $resource} service.
20
+ *
21
+ * # Error handling
22
+ * All XHR responses with response codes other then `2xx` are delegated to
23
+ * {@link angular.service.$xhr.error $xhr.error}. The `$xhr.error` can intercept the request
24
+ * and process it in application specific way, or resume normal execution by calling the
25
+ * request callback method.
26
+ *
27
+ * # Security Considerations
28
+ * When designing web applications your design needs to consider security threats from
29
+ * {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
30
+ * JSON Vulnerability} and {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}.
31
+ * Both server and the client must cooperate in order to eliminate these threats. Angular comes
32
+ * pre-configured with strategies that address these issues, but for this to work backend server
33
+ * cooperation is required.
34
+ *
35
+ * ## JSON Vulnerability Protection
36
+ * A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
37
+ * JSON Vulnerability} allows third party web-site to turn your JSON resource URL into
38
+ * {@link http://en.wikipedia.org/wiki/JSON#JSONP JSONP} request under some conditions. To
39
+ * counter this your server can prefix all JSON requests with following string `")]}',\n"`.
40
+ * Angular will automatically strip the prefix before processing it as JSON.
41
+ *
42
+ * For example if your server needs to return:
43
+ * <pre>
44
+ * ['one','two']
45
+ * </pre>
46
+ *
47
+ * which is vulnerable to attack, your server can return:
48
+ * <pre>
49
+ * )]}',
50
+ * ['one','two']
51
+ * </pre>
52
+ *
53
+ * angular will strip the prefix, before processing the JSON.
54
+ *
55
+ *
56
+ * ## Cross Site Request Forgery (XSRF) Protection
57
+ * {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which an
58
+ * unauthorized site can gain your user's private data. Angular provides following mechanism to
59
+ * counter XSRF. When performing XHR requests, the $xhr service reads a token from a cookie
60
+ * called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
61
+ * runs on your domain could read the cookie, your server can be assured that the XHR came from
62
+ * JavaScript running on your domain.
63
+ *
64
+ * To take advantage of this, your server needs to set a token in a JavaScript readable session
65
+ * cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent non-GET requests the server
66
+ * can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure that only
67
+ * JavaScript running on your domain could have read the token. The token must be unique for each
68
+ * user and must be verifiable by the server (to prevent the JavaScript making up its own tokens).
69
+ * We recommend that the token is a digest of your site's authentication cookie with
70
+ * {@link http://en.wikipedia.org/wiki/Rainbow_table salt for added security}.
13
71
*
14
72
* @param {string } method HTTP method to use. Valid values are: `GET`, `POST`, `PUT`, `DELETE`, and
15
73
* `JSON`. `JSON` is a special case which causes a
67
125
</doc:source>
68
126
</doc:example>
69
127
*/
70
- angularServiceInject ( '$xhr' , function ( $browser , $error , $log ) {
71
- var self = this ;
128
+ angularServiceInject ( '$xhr' , function ( $browser , $error , $log , $updateView ) {
72
129
return function ( method , url , post , callback ) {
73
130
if ( isFunction ( post ) ) {
74
131
callback = post ;
@@ -77,6 +134,7 @@ angularServiceInject('$xhr', function($browser, $error, $log){
77
134
if ( post && isObject ( post ) ) {
78
135
post = toJson ( post ) ;
79
136
}
137
+
80
138
$browser . xhr ( method , url , post , function ( code , response ) {
81
139
try {
82
140
if ( isString ( response ) ) {
@@ -95,8 +153,10 @@ angularServiceInject('$xhr', function($browser, $error, $log){
95
153
} catch ( e ) {
96
154
$log . error ( e ) ;
97
155
} finally {
98
- self . $eval ( ) ;
156
+ $updateView ( ) ;
99
157
}
158
+ } , {
159
+ 'X-XSRF-TOKEN' : $browser . cookies ( ) [ 'XSRF-TOKEN' ]
100
160
} ) ;
101
161
} ;
102
- } , [ '$browser' , '$xhr.error' , '$log' ] ) ;
162
+ } , [ '$browser' , '$xhr.error' , '$log' , '$updateView' ] ) ;
0 commit comments