0

I'm using YUI io to post data to my server. I have some problems sending foreign characters like æ ø å.

First case: a form is posted to the server

Y.io(url, {
    method: 'POST',
    form: {
        id: 'myform',
        useDisabled: true
    }
});

This will post the content of the form to the server. If I have a field named "test1" containing "æøå", then on the server I'll see REQUEST_CONTENT="test1=%C3%A6%C3%B8%C3%A5". This can be easily decode with a urldecode function, NO PROBLEM, but...

Second case: data is posted this way:

Y.io(uri, {
    data   : '{"test1":"æøå"}'),
    method : "POST"
});

Now I see this on the server REQUEST_CONTENT="{"test1":"├ª├©├Ñ"}". How can I decode that? And why is it send like that?

I know I can use encodeURIComponent() to encode the string before sending it. But the io request is actually part of a Model Sync operation, so I'm not calling io directly. I'm doing something like this:

Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {....});
var user = new Y.User();
user.set('test1', 'æøå');
user.save();

So it doesn't make sense to encode/decode everytime I set/read the attribute.

Also I have tried to set charset=utf-8 in the request header, but that didn't change anything.

EDIT

I have done some more debugging in chrome and the request is created with this line of code:

transaction.c.send(data);

transaction.c is the xmlhttprequest and (using chrome debugger) I can see the data is "{"test1":"æøå"}" When the above line of code is executed, a pending network entry is shown (under the network tab in chrome debugger). Request payload displays {"test1":"├ª├©├Ñ"} Headers are:

Accept:application/json
Content-Type:application/json; charset=UTF-8
Casper Skovgaard
  • 426
  • 4
  • 13

1 Answers1

0

ModelSync.REST has a serialize method that decides how the data in the model is turned into a string before passing it to Y.io. By default it uses JSON.stringify() which returns what you're seeing. You can decode it in the server using JSON. By your mention of urldecode I guess you're using PHP in the server. In that case you can use json_decode which will give you an associative array. If I'm not mistaken (I haven't used PHP in a while), it should go something like this:

$data = json_decode($HTTP_RAW_POST_DATA, true);

/*
array(1) {
  ["test1"] => "æøå"
}
*/

Another option would be for you to override the serialize method in your User model. serialize is a method used by ModelSync.REST to turn the data into a string before sending it through IO. You can replace it with a method that turns the data in the model into a regular query string using the querystring module:

Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {
  serialize: function () {
    return Y.QueryString.stringify(this.toJSON());
  }
});

Finally, ModelSync.REST assumes you'll be using JSON so you need to delete the default header so that IO uses plain text. You should add this at some point in your code:

delete Y.ModelSync.REST.HTTP_HEADERS['Content-Type'];
juandopazo
  • 6,283
  • 2
  • 26
  • 29
  • Thanks for the response @juandopazo. Unfortunately I don't use php but a Domino server. So I don't have the json_decode available. I have looked a little more into the second option. But I'm not able to make any sense of it. Using stringify like this: Y.log(Y.JSON.stringify(Y.JSON.parse('{"test1":"æøå"}'))); Will not encode the characters... Also see my edit in the question – Casper Skovgaard Jul 11 '13 at 20:26
  • Ugh! Domino! Been there. I updated my answer trying to be more clear on what `serialize` does. – juandopazo Jul 12 '13 at 21:59
  • Serialize seems like a good place to do some work. I'll give it a try. Thanks for the help. – Casper Skovgaard Jul 13 '13 at 16:41