How can I send an javascript object/array as key-value pairs via an AJAX post with easyXDM?

16,131

Solution 1

In light of the limitations of easyXDM discussed in the comments, the only way you can use it would be to serialize your data manually when passing it to .request i.e.

xhr.request({
    url: "/ajax/",
    method: "POST",
    data: {jsonData: JSON.stringify(myData)}
});

Alternatively you could create your own postMessage solution but you will be excluding IE7 and below.

Solution 2

I think you are mistaken about sending a request cross-domain via AJAX. You CAN indeed send a request cross-domain via AJAX regardless of the JavaScript API. However, in order to receive a response cross-domain, the response needs to be of data type JSONP.

JSONP is simply JSON with padding, for example:

JSON:

{ Key: "Hello", Value: "World" }

JSONP:

callback({ Key: "Hello", Value: "World" })

It is a subtle difference but JSONP by-passes browser same-origin policy and allows you to consume JSON data served by another server.

To consume JSON data coming from another server via jQuery AJAX try this:

$.ajax({
    url: "http://mydomain.com/Service.svc/GetJSONP?callback=callback",
    dataType: "jsonp",
    data: myData,
    success: function(data) {
        alert(data);
    }
});

For this to work you must make sure that your web service is returning results as JSONP and not JSON.

Solution 3

As easyXDM can't serialize properly you need to serialize data manually:

JSON.stringify(myData)

Since the request will now contain a json string rather than object then Index.html should not parse the properties to create json structure. Go to index.html that comes with easyXDM and locate the following code:

var pairs = [];
for (var key in config.data) {
    if (config.data.hasOwnProperty(key)) {
        pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(config.data[key]));
    }
}
data = pairs.join("&");

Don't execute this code in a case of POST request. Just assign config.data to data:

data = config.data;
Share:
16,131
Steve Brown
Author by

Steve Brown

Updated on June 16, 2022

Comments

  • Steve Brown
    Steve Brown almost 2 years

    Recently I realized that I needed to use easyXDM instead of jQuery's $.ajax in order to make a cross domain post request. After getting easyXDM set up I see that the functions line up fairly closely:

    jQuery:

    $.ajax({
        url: "/ajax/",
        method: "POST",
        data: myData
    });
    

    easyXDM:

    xhr.request({
        url: "/ajax/",
        method: "POST",
        dataType: 'json', // I added this trying to fix the problem, didn't work
        data: myData
    });
    

    myData is setup something like:

    myData = {};
    myData[1] = 'hello';
    myData[2] = 'goodbye';
    myData[3] = {};
    myData[3][1] = 'sub1';
    myData[3][2] = 'sub2';
    myData[3][3] = 'sub3';
    

    When I make the request with jQuery it handles the sub fields properly, but not with easyXDM.

    Here is how the POST request comes into the server with jQuery:

    screenshot-with-shadow.png http://img37.imageshack.us/img37/4526/screenshotwithshadow.png

    And here is how it comes in with easyXDM:

    screenshot-with-shadow.png http://img204.imageshack.us/img204/4526/screenshotwithshadow.png

    How can I send an javascript object/array of key-value pairs via an easyXDM / XHR request like jQuery does?

  • robC
    robC over 11 years
    easyXDM uses a hidden iframe with postMessage, not jsonp!
  • Steve Brown
    Steve Brown over 11 years
    I am trying to use easyXDM because jQuery's cross domain ajax requests are not supported in all browsers.
  • robC
    robC over 11 years
    @SteveBrown JSONP will work in all browsers. But you can't use POST it has to be a GET request.
  • Christopher.Cubells
    Christopher.Cubells over 11 years
    iframe's in general are bad news. Any web service returning JSON data which is intended to be consumed cross-domain should serve this data as JSONP. It is a simple and elegant solution using jQuery to consume this data and I highly recommend you implement this strategy rather than using easyXDM and an iframe to send your request and consume the response.
  • Steve Brown
    Steve Brown over 11 years
    @Christopher.Cubells - you're not exactly helping answer my question. I want to do a POST request and I want it to work in all browsers. I don't agree with you on iframe's in general are bad news
  • robC
    robC over 11 years
    The advantage of postMessage is that you can use POST and that you have the added security of verifying the request domain.
  • Christopher.Cubells
    Christopher.Cubells over 11 years
    You can most certainly verify the requesting domain when using a GET request as well. In the HTTP header of the request there is a key 'Referer' which will tell you the requesting domain. I apologize for overlooking that you wanted to do this only as a POST, however, is there some other reason why you must use a POST request rather than using a GET?
  • Steve Brown
    Steve Brown over 11 years
    @Christopher.Cubells - the data being sent is not going to be a fixed size and may be longer than the maximum allowed URL length.
  • Steve Brown
    Steve Brown over 11 years
    This looks like a clever workaround until that issue is hopefully resolved. I will give it a try.
  • Steve Brown
    Steve Brown over 11 years
    very clever indeed! easiest solution, at least for now! thanks! :)
  • robC
    robC over 11 years
    @SteveBrown don't forget to include a JSON implementation for IE7! github.com/douglascrockford/JSON-js
  • Steve Brown
    Steve Brown over 11 years
    thanks. easyXDM actually takes care of adding JSON support if it doesn't already exist :)