jQuery编码值与jQuery.ajax数据元素的预期值不同

时间:2010-06-09 19:48:55

标签: javascript jquery web-services rest

我正在使用jQuery.ajax()向REST Web服务发出PUT请求,但看到一些非常奇怪的序列化行为。

(在你说之前:是的,我知道并非所有浏览器都支持PUT - 这只是api / framework的一个示例实现,最终不会被浏览器调用,而是由服务器端调用 支持额外http动词的库。)

以下是表格:

<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>

和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);
        }
    });
});

使用FireBug时,我看到请求通过:

  

姓名=奥斯汀&安培;姓=韦伯&安培;地址= 25463 +主+街%2C +套件+ C&安培;城市=伯克利&安培;状态= CA&安培;邮编= 94707-4513&安培;电子邮件=奥斯汀%40life.com&安培;电话= 555 -513-4318&安培;传真= 510-513-4888&安培; thepassword = nopolyes

这并不可怕,但理想情况下,我宁愿得%20代替+空格。我尝试在转义中包装每个字段值查找:

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

但这会让事情变得更糟:

  

姓名=奥斯汀&安培;姓=韦伯&安培;地址= 25463%2520Main%2520Street%252C%2520Suite%2520C&安培;城市=伯克利&安培;状态= CA&安培;邮编= 94707-4513&安培;电子邮件=奥斯汀%40life.com&安培;电话= 555 -513-4318&安培;传真= 510-513-4888&安培; thepassword = nopolyes

在这种情况下,值被转义两次;首先,空格被编码为%20,然后%符号被转义为%25,导致%2520为空格,%252C为地址字段中的逗号

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

+是空格的正常转义字符,即使它没有在RFC1738中定义。自从永远以来,它一直被用于历史原因。这是一个大问题吗?我认为很多客户实现可能期望+也能正常工作。

答案 1 :(得分:1)

您正在使用内置对象序列化。在这种情况下自己动手:

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

或者更好的是,创建一个函数

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