From 1bd473eb4587900086e0b6b308dcf1dcfe9760d9 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Tue, 14 Oct 2014 14:51:29 -0400 Subject: [PATCH] fix($templateRequest): ignore JSON Content-Type header and content Normally, if there is a Content-Type header with the string "application/json", or else the content looks sort of JSON-y, $http will attempt to deserialize the JSON into an object. $templateRequest is intended to request markup, and as such should never attempt to parse JSON, regardless of the headers or shape of the content. Closes #5756 Closes #9619 --- src/.jshintrc | 2 ++ src/ng/http.js | 38 +++++++++++++++-------------- src/ng/templateRequest.js | 23 +++++++++++++++++- test/ng/templateRequestSpec.js | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/.jshintrc b/src/.jshintrc index 9bf99371..e833bcf0 100644 --- a/src/.jshintrc +++ b/src/.jshintrc @@ -100,6 +100,8 @@ "NODE_TYPE_DOCUMENT": false, "NODE_TYPE_DOCUMENT_FRAGMENT": false, + "httpResponseTransform": false, + /* filters.js */ "getFirstThursdayOfYear": false, diff --git a/src/ng/http.js b/src/ng/http.js index 0ae6d0ef..b190aa83 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -1,5 +1,24 @@ 'use strict'; +var APPLICATION_JSON = 'application/json'; +var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'}; +var JSON_START = /^\s*(\[|\{[^\{])/; +var JSON_END = /[\}\]]\s*$/; +var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/; + +function defaultHttpResponseTransform(data, headers) { + if (isString(data)) { + // strip json vulnerability protection prefix + data = data.replace(JSON_PROTECTION_PREFIX, ''); + 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; +} + /** * Parse headers into key value object * @@ -86,12 +105,6 @@ function isSuccess(status) { * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service. * */ function $HttpProvider() { - var JSON_START = /^\s*(\[|\{[^\{])/, - JSON_END = /[\}\]]\s*$/, - PROTECTION_PREFIX = /^\)\]\}',?\n/, - APPLICATION_JSON = 'application/json', - CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'}; - /** * @ngdoc property * @name $httpProvider#defaults @@ -115,18 +128,7 @@ function $HttpProvider() { **/ var defaults = this.defaults = { // transform incoming response data - transformResponse: [function defaultHttpResponseTransform(data, headers) { - if (isString(data)) { - // strip json vulnerability protection prefix - data = data.replace(PROTECTION_PREFIX, ''); - 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; - }], + transformResponse: [defaultHttpResponseTransform], // transform outgoing request data transformRequest: [function(d) { diff --git a/src/ng/templateRequest.js b/src/ng/templateRequest.js index 7155718e..3a232ba0 100644 --- a/src/ng/templateRequest.js +++ b/src/ng/templateRequest.js @@ -25,7 +25,28 @@ function $TemplateRequestProvider() { var self = handleRequestFn; self.totalPendingRequests++; - return $http.get(tpl, { cache : $templateCache }) + var transformResponse = $http.defaults && $http.defaults.transformResponse; + var idx; + + if (isArray(transformResponse)) { + var original = transformResponse; + transformResponse = []; + for (var i=0; i