2

I'm using jQuery.ajax() to make a PUT request to a REST web service, but seeing some really strange serialization behavior.

(Before you say it: Yes, I know that not all browsers support PUT -- this is just an example implementation for an api/framework, and ultimately will not be called by a browser, but rather by a server-side library that does support the extra http verbs.)

Here's the form:

<form action="/example/api/artist" method="put" id="update">
    First Name: <input type="text" name="firstname" /><br/>
    Last Name: <input type="text" name="lastname" /><br/>
    Address: <input type="text" name="address" /><br/>
    City: <input type="text" name="city" /><br/>
    State: <input type="text" name="state" /><br/>
    Postal Code: <input type="text" name="postalcode" /><br/>
    Email: <input type="text" name="email" /><br/>
    Phone: <input type="text" name="phone" /><br/>
    Fax: <input type="text" name="fax" /><br/>
    Password: <input type="text" name="thepassword" /><br/>
    <input type="hidden" name="debug" value="true" />
    <input type="submit" value="Update Artist" />
    <input type="reset" value="Cancel" id="updateCancel" />
</form>

And the JS:

$("#update").submit(function(e){
    e.preventDefault();
    var frm = $(this);
    $.ajax({
        url: frm.attr('action'),
        data:{
            firstname: $("#update input[name=firstname]").val(),
            lastname: $("#update input[name=lastname]").val(),
            address: $("#update input[name=address]").val(),
            city: $("#update input[name=city]").val(),
            state: $("#update input[name=state]").val(),
            postalcode: $("#update input[name=postalcode]").val(),
            email: $("#update input[name=email]").val(),
            phone: $("#update input[name=phone]").val(),
            fax: $("#update input[name=fax]").val(),
            thepassword: $("#update input[name=thepassword]").val()
        },
        type: frm.attr('method'),
        dataType: "json",
        contentType: "application/json",
        success: function (data, textStatus, xhr){
            console.log(data);
            reloadData();
        },
        error: function (xhr, textStatus, err){
            console.log(textStatus);
            console.log(err);
        }
    });
});

When using FireBug, I see the request go through as this:

firstname=Austin&lastname=Weber&address=25463+Main+Street%2C+Suite+C&city=Berkeley&state=CA&postalcode=94707-4513&email=austin%40life.com&phone=555-513-4318&fax=510-513-4888&thepassword=nopolyes

That's not horrible, but ideally I'd rather get %20 instead of + for spaces. I tried wrapping each field value lookup in an escape:

firstname: escape($("#update input[name=firstname]").val())

But that makes things worse:

firstname=Austin&lastname=Weber&address=25463%2520Main%2520Street%252C%2520Suite%2520C&city=Berkeley&state=CA&postalcode=94707-4513&email=austin%40life.com&phone=555-513-4318&fax=510-513-4888&thepassword=nopolyes

In this case, the value is being escaped twice; so first the space is encoded to %20, and then the % sign is escaped to %25 resulting in the %2520 for spaces, and %252C for the comma in the address field.

What am I doing wrong here?

2 Answers 2

2

+ is the normal escape character for spaces, even though it's not defined in RFC1738. It's been used like that for historical reasons since forever. Is it a big problem? I think a lot of your clients implementations may be expecting that + works as well.

Sign up to request clarification or add additional context in comments.

1 Comment

Turns out the framework wasn't properly decoding the url variables. Fixing that properly unencodes the +s into spaces.
1

You're using the built in object serialization. Do it yourself in this case:

data: "firstname=" + $("#update input[name=firstname]").val() + "&lastname=" // so on and so on

or better yet, make a function do it

function mySerializer(obj) { // send this your {firstname: $(...)} pairs
   $.each(obj, function(i,v,) {  // etc, etc
  });
}

1 Comment

Using this method without the escape() function I still get the %2520 junk. :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.