Keywords: AngularJS | $http.post | Request Parameters
Abstract: This article explores the issue of AngularJS $http.post sending JSON data by default, conflicting with server expectations for form-encoded parameters. By analyzing differences between jQuery and AngularJS requests, it provides two solutions: global transformRequest configuration and per-request transformRequest parameter, along with explanations of Content-Type header importance. Complete code examples and configuration instructions help developers seamlessly migrate jQuery AJAX code to AngularJS.
Problem Background and Difference Analysis
During web development migration from jQuery to AngularJS, developers often encounter inconsistencies in AJAX POST request formats. jQuery's $.post method defaults to serializing JavaScript objects into application/x-www-form-urlencoded format, i.e., param1=value1¶m2=value2. In contrast, AngularJS's $http.post method converts data to JSON string by default, formatted as {"param1":"value1","param2":"value2"}. When the server only supports form parameter format, this discrepancy results in 500 errors.
Core Solution: transformRequest Configuration
AngularJS provides the transformRequest configuration option, allowing developers to transform data before sending requests. Custom transformation functions can convert JavaScript objects to URL-encoded parameter strings.
Global Configuration Method
By modifying $httpProvider.defaults.transformRequest, the data transformation behavior for all $http requests can be changed globally. The following code uses jQuery's $.param method for transformation:
var app = angular.module('myApp');
app.config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data) {
if (data === undefined) {
return data;
}
return $.param(data);
};
});
This configuration ensures all POST request data is automatically converted to form parameter format. Additionally, the corresponding Content-Type header should be set:
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
Per-Request Configuration Method
If data transformation is only needed for specific requests, a configuration object can be passed in the $http.post call:
var transform = function(data) {
return $.param(data);
};
$http.post("/foo/bar", requestData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
transformRequest: transform
}).success(function(responseData) {
// Handle response data
});
This method is more flexible and does not affect the default behavior of other requests.
Implementation Principles and Considerations
transformRequest is a stage in AngularJS's request processing pipeline, called before sending the request, receiving original data and returning transformed data. When using $.param, ensure jQuery is loaded. If jQuery is not used, similar functionality can be implemented with native JavaScript:
function toParams(obj) {
var str = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
}
Setting the correct Content-Type header is crucial, as it informs the server how to parse the request body. Incorrect or missing headers may prevent proper parameter processing by the server.
Migration Recommendations and Best Practices
When migrating from jQuery to AngularJS, first assess the expected data formats of all AJAX endpoints. If most endpoints require form parameters, use global configuration for efficiency; if only a few do, use per-request configuration. During testing, utilize browser developer tools to monitor network requests, ensuring formats match server expectations. This approach applies not only to POST but also to other HTTP methods like PUT.