Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 7f2acca

Browse files
katsosgkalpak
authored andcommitted
fix($http): do not throw error if Content-Type is not application/json but response is JSON-like
Previously, when the response data was JSON-like, `$http` would try to `JSON.parse` them and throw if they were not actually JSON. This happened even if the `Content-Type` header was not `application/json`. As a result, it was not possible to send `text/plain` data that looked like JSON (e.g. `{abcd}`). The reason for not relying solely on the `Content-Type` is that many users serve JSON data without proper headers. This commit fixes it by returning the raw response text if `$http` fails to parse a JSON-like response, unless the `Content-Type` header has been explicitly set to `application/json` (in which case it will still fail with an error). Fixes #16027 Closes #16075
1 parent c879343 commit 7f2acca

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/ng/http.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,15 @@ function defaultHttpResponseTransform(data, headers) {
137137

138138
if (tempData) {
139139
var contentType = headers('Content-Type');
140-
if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {
140+
var hasJsonContentType = contentType && (contentType.indexOf(APPLICATION_JSON) === 0);
141+
142+
if (hasJsonContentType || isJsonLike(tempData)) {
141143
try {
142144
data = fromJson(tempData);
143145
} catch (e) {
146+
if (!hasJsonContentType) {
147+
return data;
148+
}
144149
throw $httpMinErr('baddata', 'Data must be a valid JSON object. Received: "{0}". ' +
145150
'Parse error: "{1}"', data, e);
146151
}

test/ng/httpSpec.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,8 +1402,45 @@ describe('$http', function() {
14021402
expect(errCallback.calls.mostRecent().args[0]).toEqualMinErr('$http', 'baddata');
14031403
});
14041404

1405-
});
1405+
it('should not throw an error if JSON is invalid but content-type is not application/json', function() {
1406+
$httpBackend.expect('GET', '/url').respond('{abcd}', {'Content-Type': 'text/plain'});
1407+
1408+
$http.get('/url').then(callback);
1409+
$httpBackend.flush();
1410+
1411+
expect(callback).toHaveBeenCalledOnce();
1412+
});
1413+
1414+
it('should not throw an error if JSON is invalid but content-type is not specified', function() {
1415+
$httpBackend.expect('GET', '/url').respond('{abcd}');
1416+
1417+
$http.get('/url').then(callback);
1418+
$httpBackend.flush();
1419+
1420+
expect(callback).toHaveBeenCalledOnce();
1421+
});
14061422

1423+
it('should return response unprocessed if JSON is invalid but content-type is not application/json', function() {
1424+
var response = '{abcd}';
1425+
$httpBackend.expect('GET', '/url').respond(response, {'Content-Type': 'text/plain'});
1426+
1427+
$http.get('/url').then(callback);
1428+
$httpBackend.flush();
1429+
1430+
expect(callback.calls.mostRecent().args[0].data).toBe(response);
1431+
});
1432+
1433+
it('should return response unprocessed if JSON is invalid but content-type is not specified', function() {
1434+
var response = '{abcd}';
1435+
$httpBackend.expect('GET', '/url').respond(response);
1436+
1437+
$http.get('/url').then(callback);
1438+
$httpBackend.flush();
1439+
1440+
expect(callback.calls.mostRecent().args[0].data).toBe(response);
1441+
});
1442+
1443+
});
14071444

14081445
it('should have access to response headers', function() {
14091446
$httpBackend.expect('GET', '/url').respond(200, 'response', {h1: 'header1'});

0 commit comments

Comments
 (0)