如何使用 $.ajax(jQuery 或 Zepto)发布对象数组

Posted

技术标签:

【中文标题】如何使用 $.ajax(jQuery 或 Zepto)发布对象数组【英文标题】:How do I POST an array of objects with $.ajax (jQuery or Zepto) 【发布时间】:2012-06-22 00:19:22 【问题描述】:

我想在 Zepto 或 Jquery 中使用 $.ajax 发布一组对象。两者都表现出相同的奇怪错误,但我找不到我做错了什么。

当使用“RestEasy”之类的测试客户端发送数据时,数据会保存到服务器,我可以看到请求在浏览器的网络面板中被破坏,所以我认为 JS 是罪魁祸首。

如果我将对象数组作为 POST 的数据属性发送,则它们不会被正确发送。

数据对象:

var postData = [
     "id":"1", "name":"bob"
  ,  "id":"2", "name":"jonas"
  ]

请求:

$.ajax(
  url: _saveDeviceUrl
, type: 'POST'
, contentType: 'application/json'
, dataType: 'json'
, data: postData
, success: _madeSave.bind(this)
//, processData: false //Doesn't help
);

在浏览器中看到的请求正文:

"bob=undefined&jonas=undefined"

使用 jQuery 和 Zepto 都用来准备 POST 数据的 $.param 方法可以更直接地看到这一点。

$.param(
  [
     "id":"1", "name":"bob"
  ,  "id":"2", "name":"jonas"
  ]
)
// Output: "bob=undefined&jonas=undefined"

因此,这些库为复杂的帖子数据所做的准备似乎与我预期的不同。

我看到了这个答案,但我不想将数据作为查询参数发送,因为我要发布大量内容。 How do I send an array in an .ajax post using jQuery?

使用 jQuery/Zepto 通过 POST 发送多个对象的正确方法是什么?

使用 $.ajax(... data: JSON.stringify(postData) ...) 发送未损坏的内容,但服务器不喜欢这种格式。

更新: 似乎 JSON.stringify 发送格式正确的内容。问题是服务器端对它想要的对象的结构非常非常具体。如果我从对象中添加或删除任何属性,它将使整个过程失败,而不是使用匹配的属性。这很不方便,因为使用服务器发送的内容作为视图模型很好,但是视图模型会改变。 ...仍在寻找最佳解决方案。

【问题讨论】:

您是否使用 php 接收这些数据?如果是,您可以尝试使用.serialize(),但您需要在变量名末尾添加[],并将它们作为数组接收 【参考方案1】:

发送前请务必stringify。我过于依赖库,并认为它们会根据我发布的 contentType 正确编码,但他们似乎没有。

作品:

$.ajax(
    url: _saveAllDevicesUrl
,   type: 'POST'
,   contentType: 'application/json'
,   data: JSON.stringify(postData) //stringify is important
,   success: _madeSave.bind(this)
);

我更喜欢使用这种方法而不是使用像 $.toJSON 这样的插件,尽管它确实完成了同样的事情。

【讨论】:

嘿,快来看看。我已经通过一些+= 语句将参数列表构建为 URL 格式的字符串,例如x=123&y=1234&z=12345 ...现在说实话已经很长了...很长。我也知道 URL,所以理论上我可以只做data: myParamString,还是我也需要 JSON.stringify 它?谢谢,我知道这是一个老问题 @shanehoban 在 POST 中,参数通常在正文中发送,而不是作为 URL 参数。你在做 GET 吗?无论如何,我认为这不是很相关。可能想提出一个不同的问题。 谢谢,我现在明白了 - 这是不久前的事了 :) @Simple 非常感谢! 如何告诉我们 postData 中有哪些数据,以便我们知道这个答案实际解决了什么问题。重要的是,您尝试使用哪些数据无法使用。目前所有这些答案都不完整。【参考方案2】:

尝试以下方法:

$.ajax(
  url: _saveDeviceUrl
, type: 'POST'
, contentType: 'application/json'
, dataType: 'json'
, data: 'myArray': postData
, success: _madeSave.bind(this)
//, processData: false //Doesn't help
);

【讨论】:

这是一种更好的方法,因为 javascript 中的数组本身不是 JSON。甚至 [] 也是无效的。数组需要被一个 Object 包裹在一个属性里面。 谢谢,最好的解决方案是你的。它帮助我向我的 web ASP.net api 发送了一个带有 ajax 的对象数组。【参考方案3】:

编辑:我想现在可以安全地使用原生的 JSON.stringify() 方法了,most browsers 支持(是的,如果你想知道的话,甚至是 IE8+)。

就这么简单:

JSON.stringify(yourData)

您应该在发送数据之前将数据编码为 JSON,您不能只将这样的对象作为 POST 数据发送。

我建议使用jQuery json plugin 这样做。然后你可以在 jQuery 中使用这样的东西:

$.post(_saveDeviceUrl, 
    data : $.toJSON(postData)
, function(response)
    //Process your response here

);

【讨论】:

它已经是一个 javascript 对象,我认为转换很简单或由这些库自动处理。 js对象和JSON传输对象之间究竟做了什么转换?这和 JSON.stringify 一样吗?【参考方案4】:

查看这个发布不同类型数组的例子

function PostArray() 
    var myObj = [
         'fstName': 'name 1', 'lastName': 'last name 1', 'age': 32 
      ,  'fstName': 'name 2', 'lastName': 'last name 1', 'age': 33 
    ];

    var postData = JSON.stringify( lst: myObj );
    console.log(postData);

    $.ajax(
        type: "POST",
        url: urlWebMethods + "/getNames",
        data: postData,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) 
            alert(response.d);
        ,
        failure: function (msg) 
            alert(msg.d);
        
    );

如果在 C# 中使用 WebMethod,您可以像这样检索数据

[WebMethod]
    public static string getNames(IEnumerable<object> lst)
    
        string names = "";
        try
        
            foreach (object item in lst)
            
                Type myType = item.GetType();
                IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

                foreach (PropertyInfo prop in props)
                
                    if(prop.Name == "Values")
                    
                        Dictionary<string, object> dic = item as Dictionary<string, object>;
                        names += dic["fstName"];
                    
                
            
        
        catch (Exception ex)
        
             names = "-1";
        
        return names;
    

POST an array of objects with $.ajax to C# WebMethod 中的示例

【讨论】:

【参考方案5】:

当我在 django 中接收由 ajax 发送的对象数组时,我遇到了同样的问题。 JSONStringyfy 为我工作。你可以看看这个。

首先我将数据字符串化为

var myData = [];
   allData.forEach((x, index) => 
         // console.log(index);
         myData.push(JSON.stringify(
         "product_id" : x.product_id,
         "product" : x.product,
         "url" : x.url,
         "image_url" : x.image_url,
         "price" : x.price,
         "source": x.source
      ))
   )

然后我就发了

$.ajax(
        url: '% url "url_name" %',
        method: "POST",
        data: 
           'csrfmiddlewaretoken': ' csrf_token ',
           'queryset[]': myData
        ,
        success: (res) => 
        // success post work here.
    
)

并收到:

list_of_json = request.POST.getlist("queryset[]", [])
list_of_json = [ json.loads(item) for item in list_of_json ]

【讨论】:

以上是关于如何使用 $.ajax(jQuery 或 Zepto)发布对象数组的主要内容,如果未能解决你的问题,请参考以下文章

如何使用js或jQuery向ajax请求添加自定义HTTP标头?

使用 JSONP 时如何捕获 jQuery $.getJSON(或数据类型设置为“jsonp”的 $.ajax)错误?

如何使用 jquery 或 ajax 获取外部 html 页面内容 [重复]

使用 jQuery 或 Ajax 显示或隐藏字段 [关闭]

如何使用jquery ajax检查或不检查复选框[重复]

如何使用 jquery 或 ajax 在 c#/asp.net 中为 MVC 项目更新 razor 部分视图