Skip to content

Commit 7b6c1d0

Browse files
committed
fix($http): honor application/json response header and parse json primitives
When server responds with Content-Type header set to application/json we now properly parse the response as JSON Closes angular#2973
1 parent 858360b commit 7b6c1d0

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

src/ng/http.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ function $HttpProvider() {
8989
var JSON_START = /^\s*(\[|\{[^\{])/,
9090
JSON_END = /[\}\]]\s*$/,
9191
PROTECTION_PREFIX = /^\)\]\}',?\n/,
92-
CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'};
92+
APPLICATION_JSON = 'application/json',
93+
CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
9394

9495
/**
9596
* @ngdoc property
@@ -114,12 +115,15 @@ function $HttpProvider() {
114115
**/
115116
var defaults = this.defaults = {
116117
// transform incoming response data
117-
transformResponse: [function(data) {
118+
transformResponse: [function defaultHttpResponseTransform(data, headers) {
118119
if (isString(data)) {
119120
// strip json vulnerability protection prefix
120121
data = data.replace(PROTECTION_PREFIX, '');
121-
if (JSON_START.test(data) && JSON_END.test(data))
122+
var contentType = headers('Content-Type');
123+
if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
124+
(JSON_START.test(data) && JSON_END.test(data))) {
122125
data = fromJson(data);
126+
}
123127
}
124128
return data;
125129
}],

test/ng/httpSpec.js

+55
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,61 @@ describe('$http', function() {
10201020
});
10211021

10221022

1023+
it('should deserialize json numbers when response header contains application/json',
1024+
function() {
1025+
$httpBackend.expect('GET', '/url').respond('123', {'Content-Type': 'application/json'});
1026+
$http({method: 'GET', url: '/url'}).success(callback);
1027+
$httpBackend.flush();
1028+
1029+
expect(callback).toHaveBeenCalledOnce();
1030+
expect(callback.mostRecentCall.args[0]).toEqual(123);
1031+
});
1032+
1033+
1034+
it('should deserialize json strings when response header contains application/json',
1035+
function() {
1036+
$httpBackend.expect('GET', '/url').respond('"asdf"', {'Content-Type': 'application/json'});
1037+
$http({method: 'GET', url: '/url'}).success(callback);
1038+
$httpBackend.flush();
1039+
1040+
expect(callback).toHaveBeenCalledOnce();
1041+
expect(callback.mostRecentCall.args[0]).toEqual('asdf');
1042+
});
1043+
1044+
1045+
it('should deserialize json nulls when response header contains application/json',
1046+
function() {
1047+
$httpBackend.expect('GET', '/url').respond('null', {'Content-Type': 'application/json'});
1048+
$http({method: 'GET', url: '/url'}).success(callback);
1049+
$httpBackend.flush();
1050+
1051+
expect(callback).toHaveBeenCalledOnce();
1052+
expect(callback.mostRecentCall.args[0]).toEqual(null);
1053+
});
1054+
1055+
1056+
it('should deserialize json true when response header contains application/json',
1057+
function() {
1058+
$httpBackend.expect('GET', '/url').respond('true', {'Content-Type': 'application/json'});
1059+
$http({method: 'GET', url: '/url'}).success(callback);
1060+
$httpBackend.flush();
1061+
1062+
expect(callback).toHaveBeenCalledOnce();
1063+
expect(callback.mostRecentCall.args[0]).toEqual(true);
1064+
});
1065+
1066+
1067+
it('should deserialize json false when response header contains application/json',
1068+
function() {
1069+
$httpBackend.expect('GET', '/url').respond('false', {'Content-Type': 'application/json'});
1070+
$http({method: 'GET', url: '/url'}).success(callback);
1071+
$httpBackend.flush();
1072+
1073+
expect(callback).toHaveBeenCalledOnce();
1074+
expect(callback.mostRecentCall.args[0]).toEqual(false);
1075+
});
1076+
1077+
10231078
it('should deserialize json with security prefix', function() {
10241079
$httpBackend.expect('GET', '/url').respond(')]}\',\n[1, "abc", {"foo":"bar"}]');
10251080
$http({method: 'GET', url: '/url'}).success(callback);

0 commit comments

Comments
 (0)