diff --git a/src/ng/http.js b/src/ng/http.js index e10207c57f99..272a8d5faadf 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -89,7 +89,8 @@ function $HttpProvider() { var JSON_START = /^\s*(\[|\{[^\{])/, JSON_END = /[\}\]]\s*$/, PROTECTION_PREFIX = /^\)\]\}',?\n/, - CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': 'application/json;charset=utf-8'}; + APPLICATION_JSON = 'application/json', + CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'}; /** * @ngdoc property @@ -114,12 +115,15 @@ function $HttpProvider() { **/ var defaults = this.defaults = { // transform incoming response data - transformResponse: [function(data) { + transformResponse: [function defaultHttpResponseTransform(data, headers) { if (isString(data)) { // strip json vulnerability protection prefix data = data.replace(PROTECTION_PREFIX, ''); - if (JSON_START.test(data) && JSON_END.test(data)) + var contentType = headers('Content-Type'); + if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) || + (JSON_START.test(data) && JSON_END.test(data))) { data = fromJson(data); + } } return data; }], diff --git a/test/ng/httpSpec.js b/test/ng/httpSpec.js index c26c84334eca..f76aaec81371 100644 --- a/test/ng/httpSpec.js +++ b/test/ng/httpSpec.js @@ -1020,6 +1020,61 @@ describe('$http', function() { }); + it('should deserialize json numbers when response header contains application/json', + function() { + $httpBackend.expect('GET', '/url').respond('123', {'Content-Type': 'application/json'}); + $http({method: 'GET', url: '/url'}).success(callback); + $httpBackend.flush(); + + expect(callback).toHaveBeenCalledOnce(); + expect(callback.mostRecentCall.args[0]).toEqual(123); + }); + + + it('should deserialize json strings when response header contains application/json', + function() { + $httpBackend.expect('GET', '/url').respond('"asdf"', {'Content-Type': 'application/json'}); + $http({method: 'GET', url: '/url'}).success(callback); + $httpBackend.flush(); + + expect(callback).toHaveBeenCalledOnce(); + expect(callback.mostRecentCall.args[0]).toEqual('asdf'); + }); + + + it('should deserialize json nulls when response header contains application/json', + function() { + $httpBackend.expect('GET', '/url').respond('null', {'Content-Type': 'application/json'}); + $http({method: 'GET', url: '/url'}).success(callback); + $httpBackend.flush(); + + expect(callback).toHaveBeenCalledOnce(); + expect(callback.mostRecentCall.args[0]).toEqual(null); + }); + + + it('should deserialize json true when response header contains application/json', + function() { + $httpBackend.expect('GET', '/url').respond('true', {'Content-Type': 'application/json'}); + $http({method: 'GET', url: '/url'}).success(callback); + $httpBackend.flush(); + + expect(callback).toHaveBeenCalledOnce(); + expect(callback.mostRecentCall.args[0]).toEqual(true); + }); + + + it('should deserialize json false when response header contains application/json', + function() { + $httpBackend.expect('GET', '/url').respond('false', {'Content-Type': 'application/json'}); + $http({method: 'GET', url: '/url'}).success(callback); + $httpBackend.flush(); + + expect(callback).toHaveBeenCalledOnce(); + expect(callback.mostRecentCall.args[0]).toEqual(false); + }); + + it('should deserialize json with security prefix', function() { $httpBackend.expect('GET', '/url').respond(')]}\',\n[1, "abc", {"foo":"bar"}]'); $http({method: 'GET', url: '/url'}).success(callback);