How do I POST urlencoded form data with $http without jQuery?
I am new to AngularJS, and for a start, I thought to develop a new application using only AngularJS.
I am trying to make an AJAX call to the server side, using $http
from my Angular App.
For sending the parameters, I tried the following:
$http({
method: "post",
url: URL,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $.param({username: $scope.userName, password: $scope.password})
}).success(function(result){
console.log(result);
});
This is working, but it is using jQuery as well at $.param
. For removing the dependency on jQuery, I tried:
data: {username: $scope.userName, password: $scope.password}
but this seemed to fail. Then I tried params
:
params: {username: $scope.userName, password: $scope.password}
but this also seemed to fail. Then I tried JSON.stringify
:
data: JSON.stringify({username: $scope.userName, password: $scope.password})
I found these possible answers to my quest, but was unsuccessful. Am I doing something wrong? I am sure, AngularJS would provide this functionality, but how?
I think you need to do is to transform your data from object not to JSON string, but to url params.
From Ben Nadel's blog.
By default, the $http service will transform the outgoing request by serializing the data as JSON and then posting it with the content- type, "application/json". When we want to post the value as a FORM post, we need to change the serialization algorithm and post the data with the content-type, "application/x-www-form-urlencoded".
Example from here.
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {username: $scope.userName, password: $scope.password}
}).then(function () {});
UPDATE
To use new services added with AngularJS V1.4, see
- URL-encoding variables using only AngularJS services
URL-encoding variables using only AngularJS services
With AngularJS 1.4 and up, two services can handle the process of url-encoding data for POST requests, eliminating the need to manipulate the data with transformRequest
or using external dependencies like jQuery:
-
$httpParamSerializerJQLike
- a serializer inspired by jQuery's.param()
(recommended) -
$httpParamSerializer
- a serializer used by Angular itself for GET requests
Example with $http()
$http({
url: 'some/api/endpoint',
method: 'POST',
data: $httpParamSerializerJQLike($scope.appForm.data), // Make sure to inject the service you choose to the controller
headers: {
'Content-Type': 'application/x-www-form-urlencoded' // Note the appropriate header
}
}).then(function(response) { /* do something here */ });
See a more verbose Plunker demo
Example with $http.post()
$http.post(
'some/api/endpoint',
data: $httpParamSerializerJQLike($scope.appForm.data), // Make sure to inject the service you choose to the controller
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded' // Note the appropriate header
}
}
).then(function
How are $httpParamSerializerJQLike
and $httpParamSerializer
different
In general, it seems $httpParamSerializer
uses less "traditional" url-encoding format than $httpParamSerializerJQLike
when it comes to complex data structures.
For example (ignoring percent encoding of brackets):
• Encoding an array
{sites:['google', 'Facebook']} // Object with array property
sites[]=google&sites[]=facebook // Result with $httpParamSerializerJQLike
sites=google&sites=facebook // Result with $httpParamSerializer
• Encoding an object
{address: {city: 'LA', country: 'USA'}} // Object with object property
address[city]=LA&address[country]=USA // Result with $httpParamSerializerJQLike
address={"city": "LA", country: "USA"} // Result with $httpParamSerializer