I am trying to submit a POST
request to a server which only accepts the data in the x-www-form-urlencoded
format.
When I test it out on Postman, it works. For example, the preview header looks like:
POST /api/signin HTTP/1.1
Host: myproj.herokuapp.com
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
email=joe%40gmail.com&password=1234567
However, when I run it from my app, the header, as viewed in Chrome console, looks like:
Remote Address:10.10.10.250:80
Request URL:http://myproj.herokuapp.com/api/signIn
Request Method:POST
Status Code:400 Bad Request
Request Headersview source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:53
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:rapidit.herokuapp.com
Origin:http://localhost
Referer:http://localhost/rapid/v3/src/app/index/
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Form Dataview parsed
{"email":"[email protected]","password":"1234567"}
Clearly, it's not sending the data in the right format.
This is what it looks like in my Angular factory (with hardcoded login data):
var LoginResource = $resource("http://myproj.herokuapp.com/api/signIn", {}, {
post: {
method: "POST",
isArray: false,
headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}
}
});
var loginUser = function (){
return LoginResource.post(
{
email: "[email protected]",
password: "1234567"
}
).$promise; //this promise will be fulfilled when the response is retrieved for this call
};
return loginUser;
How can I get the data to POST in the required format?
By default Angular uses application/json and it's not enough to set the header to form url encode, you have to actually transform the data, you can do that by using de transformRequest option on the $resource service. This is how it looks like.
angular.module("AuthModule")
.factory("authResource", ['$resource', 'appSettings', function ($resource, appSettings) {
return {
login: $resource(appSettings.serverPath + '/Token', null,
{
loginUser: {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
transformRequest: function (data, headersGetter) {
var str = [];
for (var d in data)
str.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
return str.join("&");
}
},
})
}
}]);
P/D: I didn't write this. This code was taken from a pluralsight's course, called Angular Front to Back with Web API.
Since angularjs 1.4, you can use $httpParamSerializer:
function transformUrlEncoded(data) {
return $httpParamSerializer(parameters);
}
...
$resource('http://myproj.herokuapp.com/api/signIn', {}, {
post: {
method: "POST",
headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: transformUrlEncoded
}
});
I had a similar problem, AngularJS $resource service posts the data in JSON format by default, i.e. if you check the Content-type header in the request you'll see Content-type: application/json
.
In my case my server can handle those payloads, but found a Google thread that might help in your case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With