Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dojo dojo.rawXhrPost and dojo.xhrPost

Tags:

json

dojo

My question is: can we use dojo.xhrPost to post some Json data? More detail:

I have been experimenting with Dojo code to POST JSON data to a RESTful service. It seems to be that the behaviours of dojo.xhrPost and dojo.rawXhrPost are different, or to be more accurate rawXhrPost() works and xhrPost() does not. This is not consistent with my reading of the docs

The original purpose of dojo.rawXhrPost was a method that could be used to send a raw post body to the server. As of 1.3, this function is common with dojo.xhrPost(). So, for usage of dojo.rawXhrPost(), see dojo.xhrPost()

Which implies that xhrPost() is enough. My code looks like this - I've got a "toy" library service that manages Editions of Books. The code wants to POST a new entry,

        var myEdition = {"Edition":{"isbn":"44"}};

        var xhrArgs = {
            url: "http://localhost:8081/LibraryWink/library/editions",
            postData: dojo.toJson(myEdition),
            handleAs: "json",
            headers: { "Content-Type": "application/json"},

            load: function(data) {
                dojo.byId("mainMessageText").innerHTML = "Message posted.";
            },
            error: function(error) {

                dojo.byId("mainMessageText").innerHTML = "Error :" + error;
            }
        };

        var deferred = dojo.rawXhrPost(xhrArgs);

The headers: { "Content-Type": "application/json"} part in necessary so that my JAX-RC service understands that the content is JSON.

What I find is that the code above works perfectly. However if instead I say:

var deferred = dojo.xhrPost(xhrArgs);

No data is transmitted in the POST. I have a TCP/IP monitor in place and can see that there is nothing transmitted.

So, is this a bug, or am I driving xhrPost() incorrectly? Or should I use rawXhrPost()? If the latter, under what circumstances do we use the two flavours of XhrPost?

like image 870
djna Avatar asked Dec 04 '09 13:12

djna


3 Answers

As of DOJO 1.4 the this should work:

var myEdition = {"Edition":{"isbn":"44"}};

var xhrArgs = {
    url: "http://localhost:8081/LibraryWink/library/editions",
    postData: dojo.toJson(myEdition),
    handleAs: "json",
    headers: { "Content-Type": "application/json"},
    load: function(data) {
        dojo.byId("mainMessageText").innerHTML = "Message posted.";
    },
    error: function(error) {

        dojo.byId("mainMessageText").innerHTML = "Error :" + error;
    }
};

dojo.xhrPost(xhrArgs);

If you are posting JSON data, the Content-Type header is critical. If you don't add it, the browser will default to 'application/x-www-form-urlencoded' and URL encode your data for you.

You may want to add a charset to the Content-Type header (I do this) but that does not stop it from functioning:

    headers: { "Content-Type": "application/json; charset=utf-8"}

On Firefox 3.6 at least, the charset is automatically added.

As Dom mentions, the HTTP PUT equivalent is dojo.xhrPut. The difference here is that you need to add your request body data as putData instead of postData.

like image 130
lambacck Avatar answered Sep 29 '22 06:09

lambacck


While using Dojo library from http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js, I've no issue posting data from a form (data serialized by dojo.formToJson()).

dojo.xhrPut({
    putData: dojo.formToJson("locationInformation"),
    handleAs: "json",
    load: function(response, ioArgs) {
        // ... business logic ...
    },
    error: function(message, ioArgs) { alert(message+"\nurl: "+ioArgs.url); },
    url: "/API/Location"
});

Using Firebug in Firefox, I can see that my request is built as expected:

  • Among other request headers: Content-Type = application/json; charset=UTF-8
  • Body of the Put request: {"postalCode":"h8p3r8","countryCode":"CA"}

xhrPost/xhrPut seem to work as rawXhrPost/rawXhrPut...

like image 44
Dom Derrien Avatar answered Sep 29 '22 04:09

Dom Derrien


One more thing that I would like to add the the answer. When working with AJAX apps, it's also a good idea to set the Accept value to application/json when that's what you're expecting.

headers: { "Content-Type": "application/json", "Accept" : "application/json"}
like image 32
Richard Ayotte Avatar answered Sep 29 '22 04:09

Richard Ayotte