mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-08 22:37:20 +08:00
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
This commit is contained in:
@@ -100,6 +100,8 @@
|
|||||||
"NODE_TYPE_DOCUMENT": false,
|
"NODE_TYPE_DOCUMENT": false,
|
||||||
"NODE_TYPE_DOCUMENT_FRAGMENT": false,
|
"NODE_TYPE_DOCUMENT_FRAGMENT": false,
|
||||||
|
|
||||||
|
"httpResponseTransform": false,
|
||||||
|
|
||||||
/* filters.js */
|
/* filters.js */
|
||||||
"getFirstThursdayOfYear": false,
|
"getFirstThursdayOfYear": false,
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,24 @@
|
|||||||
'use strict';
|
'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
|
* 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.
|
* Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.
|
||||||
* */
|
* */
|
||||||
function $HttpProvider() {
|
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
|
* @ngdoc property
|
||||||
* @name $httpProvider#defaults
|
* @name $httpProvider#defaults
|
||||||
@@ -115,18 +128,7 @@ function $HttpProvider() {
|
|||||||
**/
|
**/
|
||||||
var defaults = this.defaults = {
|
var defaults = this.defaults = {
|
||||||
// transform incoming response data
|
// transform incoming response data
|
||||||
transformResponse: [function defaultHttpResponseTransform(data, headers) {
|
transformResponse: [defaultHttpResponseTransform],
|
||||||
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;
|
|
||||||
}],
|
|
||||||
|
|
||||||
// transform outgoing request data
|
// transform outgoing request data
|
||||||
transformRequest: [function(d) {
|
transformRequest: [function(d) {
|
||||||
|
|||||||
@@ -25,7 +25,28 @@ function $TemplateRequestProvider() {
|
|||||||
var self = handleRequestFn;
|
var self = handleRequestFn;
|
||||||
self.totalPendingRequests++;
|
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<original.length; ++i) {
|
||||||
|
var transformer = original[i];
|
||||||
|
if (transformer !== defaultHttpResponseTransform) {
|
||||||
|
transformResponse.push(transformer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (transformResponse === defaultHttpResponseTransform) {
|
||||||
|
transformResponse = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpOptions = {
|
||||||
|
cache: $templateCache,
|
||||||
|
transformResponse: transformResponse
|
||||||
|
};
|
||||||
|
|
||||||
|
return $http.get(tpl, httpOptions)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
var html = response.data;
|
var html = response.data;
|
||||||
if(!html || html.length === 0) {
|
if(!html || html.length === 0) {
|
||||||
|
|||||||
@@ -86,4 +86,48 @@ describe('$templateRequest', function() {
|
|||||||
expect($templateRequest.totalPendingRequests).toBe(0);
|
expect($templateRequest.totalPendingRequests).toBe(0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should not try to parse a response as JSON',
|
||||||
|
inject(function($templateRequest, $httpBackend) {
|
||||||
|
var spy = jasmine.createSpy('success');
|
||||||
|
$httpBackend.expectGET('a.html').respond('{{text}}', {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
$templateRequest('a.html').then(spy);
|
||||||
|
$httpBackend.flush();
|
||||||
|
expect(spy).toHaveBeenCalledOnceWith('{{text}}');
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should use custom response transformers (array)', function() {
|
||||||
|
module(function($httpProvider) {
|
||||||
|
$httpProvider.defaults.transformResponse.push(function(data) {
|
||||||
|
return data + '!!';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
inject(function($templateRequest, $httpBackend) {
|
||||||
|
var spy = jasmine.createSpy('success');
|
||||||
|
$httpBackend.expectGET('a.html').respond('{{text}}', {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
$templateRequest('a.html').then(spy);
|
||||||
|
$httpBackend.flush();
|
||||||
|
expect(spy).toHaveBeenCalledOnceWith('{{text}}!!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use custom response transformers (function)', function() {
|
||||||
|
module(function($httpProvider) {
|
||||||
|
$httpProvider.defaults.transformResponse = function(data) {
|
||||||
|
return data + '!!';
|
||||||
|
};
|
||||||
|
});
|
||||||
|
inject(function($templateRequest, $httpBackend) {
|
||||||
|
var spy = jasmine.createSpy('success');
|
||||||
|
$httpBackend.expectGET('a.html').respond('{{text}}', {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
});
|
||||||
|
$templateRequest('a.html').then(spy);
|
||||||
|
$httpBackend.flush();
|
||||||
|
expect(spy).toHaveBeenCalledOnceWith('{{text}}!!');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user