2010-06-09 55 views
2

我正在使用jQuery.ajax()向REST Web服務發出PUT請求,但看到一些非常奇怪的序列化行爲。 (在你說出來之前:是的,我知道並非所有的瀏覽器都支持PUT--這只是api/framework的一個示例實現,最終不會被瀏覽器調用,而是由服務器端實現, 。邊庫確實支持額外的HTTP動詞)jQuery編碼值與jQuery.ajax數據元素的預期值不同

這裏的形式:

<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

+是位普通的轉義字符,即使它不是在RFC1738中定義。從歷史的角度來看,它一直是這樣使用的,因爲它永遠都是。這是一個大問題嗎?我認爲很多客戶的實現可能會期望+也可以。

+0

原來這個框架沒有正確解碼url變量,修正了將+ s正確地解碼爲空格的問題。 – 2010-06-09 22:10:54

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 
    }); 
} 
+0

使用這個方法沒有escape()函數我仍然得到'%2520'垃圾。 :( – 2010-06-09 22:03:25