Angulars $http.post rationale

The comparable jQuery function

$.post("/example/handler", {foo: 1, bar: 2});

will create a request with the post parameters foo=1&bar=2. Whereas

$http.post("/example/handler", {foo : 1, bar: 2});

seems to send a POST request with the body {"foo":1,"bar":2} rather than the form-uriencoded version. To get what I think is the expected behavior here, I need to do something like

myModule.config(function ($httpProvider) {
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
    $httpProvider.defaults.transformRequest = function(data){
        return _.map(data, function (val, k) { return encodeURI(k) + "=" + encodeURI(val); }).join("&");
    }
});

in the module config.

Can anyone explain the rationale behind $http.post argument handling? Is there a situation where I'd want Angulars' default behavior, or some hidden advantage I'm not seeing?

I'm not too familiar with the HTTP protocol, but aren't POST requests normally used to send content, not parameters? Normally, I think GET is used with parameters.

I think you should be able to add a config object to the POST request, and specify the params property:

params – {Object.} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.

So maybe something like this will work:

$http.post("/example/handler", {}, {params: {foo: 1, bar: 2} })

(Above code snippet is untested... I'm not sure the syntax is correct.)

I think you answered your own question. Converting a JS object to form encoding takes work and gets tricky for more complicated structures, while converting JS objects to JSON is trivial and therefor default. What back-end are you using that's having trouble accepting JSON encoding?