Jquery Ajax 将 JSON 发布到 Web 服务

Posted

技术标签:

【中文标题】Jquery Ajax 将 JSON 发布到 Web 服务【英文标题】:Jquery Ajax Posting JSON to webservice 【发布时间】:2011-09-13 11:30:32 【问题描述】:

我正在尝试将 JSON 对象发布到 asp.net 网络服务。

我的 json 看起来像这样:

var markers =  "markers": [
   "position": "128.3657142857143", "markerPosition": "7" ,
   "position": "235.1944023323615", "markerPosition": "19" ,
   "position": "42.5978231292517", "markerPosition": "-3" 
];

我正在使用 json2.js 对我的 JSON 对象进行字符串化。

我正在使用 jquery 将其发布到我的网络服务。

  $.ajax(
        type: "POST",
        url: "/webservices/PodcastService.asmx/CreateMarkers",
        data: markers,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(data)alert(data);,
        failure: function(errMsg) 
            alert(errMsg);
        
  );

我收到以下错误:

无效的 JSON 原语

我发现了一堆与此相关的帖子,这似乎是一个非常常见的问题,但我没有尝试解决这个问题。

当萤火虫发布到服务器时,它看起来像这样:

markers%5B0%5D%5Bposition%5D=128.3657142857143&markers%5B0%5D%5BmarkerPosition%5D=7&markers%5B1%5D%5Bposition%5D=235.1944023323615&markers%5B1%5D%5BmarkerPosition%5D=19&markers%5B2% %5Bposition%5D=42.5978231292517&markers%5B2%5D%5BmarkerPosition%5D=-3

我正在调用的网络服务函数是:

[WebMethod]
public string CreateMarkers(string markerArray)

    return "received markers";

【问题讨论】:

在api.jquery.com/jQuery.ajax 中列出的设置中没有提供“失败”作为可能的设置...也许您将其误认为是“错误”? 【参考方案1】:

您提到使用 json2.js 对数据进行字符串化,但 POST 的数据似乎是 URLEncoded JSON 您可能已经看过,但this post about the invalid JSON primitive 说明了 JSON 被 URLEncoded 的原因。

我会advise against passing a raw, manually-serialized JSON string into your method。 ASP.NET 将自动对请求的 POST 数据进行 JSON 反序列化,因此,如果您手动序列化 JSON 字符串并将其发送到 ASP.NET,您实际上最终将不得不对 JSON 序列化字符串进行 JSON 序列化。

我会建议更多类似的内容:

var markers = [ "position": "128.3657142857143", "markerPosition": "7" ,
                "position": "235.1944023323615", "markerPosition": "19" ,
                "position": "42.5978231292517", "markerPosition": "-3" ];

$.ajax(
    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify( Markers: markers ),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data)alert(data);,
    error: function(errMsg) 
        alert(errMsg);
    
);

避免无效 JSON 原语问题的关键是向 jQuery 传递 data 参数的 JSON 字符串,而不是 javascript 对象,这样 jQuery 就不会尝试对您的数据进行 URLEncode。

在服务器端,将您的方法的输入参数与您传入的数据的形状相匹配:

public class Marker

  public decimal position  get; set; 
  public int markerPosition  get; set; 


[WebMethod]
public string CreateMarkers(List<Marker> Markers)

  return "Received " + Markers.Count + " markers.";

如果您愿意,也可以接受一个数组,例如 Marker[] Markers。 ASMX ScriptServices 使用的反序列化器 (JavaScriptSerializer) 非常灵活,并且会尽其所能将您的输入数据转换为您指定的服务器端类型。

【讨论】:

您写道“这样 jQuery 就不会尝试对您的数据进行 URLEncode。”,但它不正确。要阻止 jquery 对您的数据进行 urlencoding,您必须将 processData 设置为 false。 传入一个字符串就足以防止jQuery对数据参数进行URLEncoding。您可以将 processData 设置为 false,但这是多余的(单独这样做,而不为数据传递 JSON 字符串是不够的)。 同样的问题(和答案)也适用于 Rails。 @DaveWard 如果我们使用 GET 而不是 POST,是否考虑 contentType 使用file_get_contents('php://input')php 中获取您的json 数据。【参考方案2】:
    markers 不是 JSON 对象。它是一个普通的 JavaScript 对象。 Read about the data: option:

    要发送到服务器的数据。它被转换为查询字符串,如果还不是字符串的话。

如果要以 JSON 格式发送数据,则必须先对其进行编码:

data: markers: JSON.stringify(markers)

jQuery 不会自动将对象或数组转换为 JSON。


但我认为错误消息来自解释服务的响应。您发回的文本不是 JSON。 JSON 字符串必须用双引号括起来。所以你必须这样做:

return "\"received markers\"";

我不确定您的实际问题是发送还是接收数据。

【讨论】:

感谢您帮助 Felix,我认为通过 JSON.stringyfy 方法运行标记我正在将其转换为查询字符串,我已按照您的建议完成但不幸的是它不起作用我不是发布以下内容。 markers=%7B%22markers%22%3A%5B%7B%22position%22%3A%22128.3657142857143%22%2C%22markerPosition%22%3A%227%22%7D%2C%7B %22position%22%3A%22235.1944023323615%22%2C%22markerPosition%22%3A%2219%22%7D%2C%7B%22position%22%3A%2242.5978231292517%22%2C%22markerPosition%22%3A%22-3 %22%7D%5D%7D @Dreamguts:我有点不清楚你想要什么。是否要将 markers 作为 JSON 字符串发送? 嗨 Felix,是的,我想将标记对象作为 JSON 字符串发送,以便我可以在我的网络服务中使用它。 @Dreamguts:那么它应该以这种方式工作。您在评论中发布的“代码”也看起来不错。当然你得在服务器端正确解码,也许你必须改变参数的名称,我不知道。【参考方案3】:

我尝试了 Dave Ward 的解决方案。由于 contentType 设置为 "application/json",因此未在发布请求的有效负载部分中从浏览器发送数据部分。一旦我删除了这条线,一切都很好。

var markers = [ "position": "128.3657142857143", "markerPosition": "7" ,

                "position": "235.1944023323615", "markerPosition": "19" ,

                "position": "42.5978231292517", "markerPosition": "-3" ];

$.ajax(

    type: "POST",
    url: "/webservices/PodcastService.asmx/CreateMarkers",
    // The key needs to match your method's input parameter (case-sensitive).
    data: JSON.stringify( Markers: markers ),
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data)alert(data);,
    failure: function(errMsg) 
        alert(errMsg);
    
);

【讨论】:

我正在使用服务器,我无权访问。我删除了 contentType,它有帮助。但是有效载荷在有和没有它的情况下都在传递。别的东西变了。 contentType 更改为“application/x-www-form-urlencoded”,这是错误的,但可以。魔法。谢谢。【参考方案4】:

我也遇到过这个,这是我的解决方案。

如果您在解析数据时遇到了无效的 json 对象异常,即使您知道您的 json 字符串是正确的,请在将 ajax 代码中收到的数据字符串化后再将其解析为 JSON:

$.post(CONTEXT+"servlet/capture",
        yesTransactionId : yesTransactionId, 
        productOfferId : productOfferId
        ,
        function(data)
            try
                var trimData = $.trim(JSON.stringify(data));
                var obj      = $.parseJSON(trimData);
                if(obj.success == 'true') 
                    //some codes ...

【讨论】:

【参考方案5】:

请按照这个通过ajax调用java的webservice 变量参数 = 字段名称:字段值 ; JSON.stringify(data : param)

$.ajax(
            dataType    : 'json',
            type        : 'POST',
            contentType : 'application/json',
            url         : '<%=request.getContextPath()%>/rest/priceGroups',
            data        : JSON.stringify(data : param),
            success     : function(res) 
                if(res.success == true)
                    $('#alertMessage').html('Successfully price group created.').addClass('alert alert-success fade in');
                    $('#alertMessage').removeClass('alert-danger alert-info');
                    initPriceGroupsList();
                    priceGroupId = 0;
                    resetForm();                                                                    
                else                          
                    $('#alertMessage').html(res.message).addClass('alert alert-danger fade in');
                
                $('#alertMessage').alert();         
                window.setTimeout(function()  
                    $('#alertMessage').removeClass('in');
                    document.getElementById('message').style.display = 'none';
                , 5000);
            
        );

【讨论】:

这里如何列出对象传递到json到java webservice的ajax调用。

以上是关于Jquery Ajax 将 JSON 发布到 Web 服务的主要内容,如果未能解决你的问题,请参考以下文章

jQuery - 使用 ajax 调用将 JSON 发送到 WCF 服务为空

jQuery 使用 jQuery ajax json、php 将项目填充到 Select 中

使用 jQuery 的 $.ajax() 将多个 Json 对象作为数据传递

JQUERY ajax 将 JSON 发布到 C# MVC 控制器,但传入的数据为空

jQuery插件:Ajax将Json数据自动绑定到Form表单

JSON 格式(通过 jQuery AJAX 发送 JSON 到 Java/Wicket 服务器)