在jQuery中将数据序列化为JSON

1233
我需要将一个对象serializeJSON格式。我使用jQuery。是否有一种“标准”的方法来完成这个任务?
我的具体情况是:我定义了一个如下所示的数组:
var countries = new Array();
countries[0] = 'ga';
countries[1] = 'cd';
...

我需要将这个转换为字符串,以便像这样传递给$.ajax()

$.ajax({
    type: "POST",
    url: "Concessions.aspx/GetConcessions",
    data: "{'countries':['ga','cd']}",
...

22
没有人指出countries是一个变量名,而不是一个键名……当你尝试将其序列化时,这个信息会丢失。 - mpen
6
是的,需要使用JSON.stringify({countries:countries})。 - Bodman
2
Angular.js有:angular.fromJson和angular.toJson...所以如果你已经在使用Angular,那太棒了! - CommaToast
http://stackoverflow.com/questions/38408348/how-to-return-json-array-from-controller-and-display-in-jquery-success/38408411#38408411 - Suraj Roy
11个回答

1158

JSON-js - JavaScript中的JSON。

要将对象转换为字符串,请使用JSON.stringify

var json_text = JSON.stringify(your_object, null, 2);

要将JSON字符串转换为对象,请使用JSON.parse

var your_object = JSON.parse(json_text);

John Resig 最近推荐:

...请开始将使用 JSON 的应用程序迁移到 Crockford 的 json2.js。它完全兼容 ECMAScript 5 规范,如果存在本地(更快!)实现,则会优雅地降级。

事实上,我昨天刚在 jQuery 中引入了一个变化,利用了 JSON.parse 方法,现在它已经完全指定。

在 JavaScript 方面,我倾向于相信他的话 :)

所有现代浏览器(以及许多不古老的旧浏览器)都原生支持 JSON 对象。Crockford 的 JSON 库的当前版本仅在未定义时才定义 JSON.stringifyJSON.parse,使任何浏览器本地实现保持不变。


15
@Mark0978 的观点很好。仅作说明,关于 JSON.stringify 中的参数解释可以在这里找到:https://developer.mozilla.org/En/Using_JSON_in_Firefox#Converting_objects_into_JSON。我还没有看到第二个参数的好用例子,但最后一个参数非常有用:它指定当格式化 JSON 字符串时要使用多少个空格来缩进。 - user18015
1
在使用此解决方案之前,请检查问题:[https://github.com/douglascrockford/JSON-js/pull/13]也许更安全的方法是调整此代码,创建一些JSON2对象并在浏览器中无论是否支持JSON都使用它。 - xmedeko
1
@pat ,第二个“replacer”参数对于自定义已知对象的序列化非常有用。例如,我正在使用以下方法序列化 SVG 元素:JSON.stringify(obj, function(key, val) { if (val instanceof SVGSVGElement) {return val.xml || new XMLSerializer().serializeToString(val);} return val;}) - Courtney Christensen
Crockford的代码与一些更复杂的jQuery选择器不兼容。当我将文件底部的Object.prototype修改注释掉后,它按预期工作。 - Chris
我个人更喜欢JSON3。它支持AMD/requireJS,并且不使用eval,这正如Crockform本人所说的那样“邪恶”。https://github.com/bestiejs/json3 - Shital Shah

184

我已经使用jquery-json进行了6个月,它非常好用。使用起来非常简单:

var myObj = {foo: "bar", "baz": "wockaflockafliz"};
$.toJSON(myObj);

// Result: {"foo":"bar","baz":"wockaflockafliz"}

13
如果您已经在使用jQuery,这就是最好的选择。JSON-js作为一个独立的库非常棒,但是这个插件可以无缝地将JSON.stringify和JSON.parse与jQuery集成。这是一种双赢的选择。我的看法是,这应该成为被接受的答案。 - Evan Plaice
7
@EvanPlaice - 你说的“seamless integrates”是什么意思?使用jquery-json而不是JSON-js,我能得到什么好处? - ripper234
6
我的意思是,如果本地有JSON.stringify/JSON.parse方法,它将使用这些方法,否则它将退回到自己的实现。基本上,它是用于JSON序列化的兼容性填充程序。好处是,无论用户的浏览器是否原生支持,您都可以获得客户端JSON序列化。 - Evan Plaice
1
我一直在寻找IE6的JSON.stringify替代方案,这是目前唯一有效的一个。我的意思是,手动包含json.js很好用,但会与jQuery的"$"命名空间产生冲突。 - matewka
1
@EvanPlaice,jquery-json不是polyfill。它是一个库,如果可用,使用本地功能。相反,JSON-js(特别是json2.js)是一个polyfill,因为它提供与浏览器提供的相同的JSON对象和API,但不破坏本地功能(这意味着现代浏览器仍然可以获得高性能的本地实现)。 - Matthew Flaschen

101

47

我没有用过,但你可以尝试由Mark Gibson编写的 jQuery插件

它添加了两个函数:$.toJSON(value)$.parseJSON(json_str, [safe])


20
请注意,现在$.parseJSON已经是jQuery核心的一部分。 - Marnen Laibow-Koser

37

不,将数据序列化为JSON的标准方式是使用现有的JSON序列化库。如果您不想这样做,那么您就需要编写自己的序列化方法。

如果您需要指导如何操作,我建议您检查一些可用库的源代码。

编辑: 我不会明确表示编写自己的序列化方法是不好的,但您必须考虑到,如果对于您的应用程序来说使用格式正确的JSON很重要,那么您必须衡量“一个更多依赖”的开销和您的自定义方法可能某天会遇到您没有预料到的故障情况之间的风险。是否接受这种风险取决于你自己。


82
自己编写JSON序列化方法是不好的。我已经说出来了。 :-) - Ryan Duffield
28
重复别人已经做过的事情是不好的。我们大多数人为完成工作而获得报酬,而不是重新发明轮子。 - jamesmortensen

30

我确实在某处找到了这个信息。虽然我记不清具体在哪里了...可能是在 StackOverflow 上 :)

$.fn.serializeObject = function(){
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

6
你可以在这里找到它:https://dev59.com/f3M_5IYBdhLWcg3w4nfb#1186309 - Marcello Nuccio
这并不会将对象序列化为JSON字符串。 - Jay Taylor
4
请前往网站的网络表格页面,在FB Console中加载Jquery代码,然后运行此代码:var data = "" + $.toJSON($('form').serializeObject());。data现在是一个JSON字符串。之后运行此代码:alert(typeof data);,它应该会弹出"string"。然后运行此代码:alert(data);,你应该会看到JSON文本。最后,前往http://jsonlint.com并粘贴JSON字符串。它应该被验证为“Valid JSON”。我不确定我是否理解你的意思,因为一切似乎都指向这将生成有效的JSON。再次感谢。 - jamesmortensen
我在服务器上遇到了 $.toJSON 不是一个函数 的问题,所以我包含了 <script src="http://www.x-non.com/json/jquery.json-2.4.min.js"> </script> - rubo77
1
@rubo77 - 我不太记得我为什么要使用jquery-json。这是2-3/4年前发布的,我认为当时尝试支持IE7和IE6仍然很酷,因为它们没有内置的JSON解析器。实际上,您可以将$.toJSON替换为JSON.stringify,在不需要外部依赖项的情况下获得相同的结果,假设您只支持现代浏览器。希望这可以帮助您! :) - jamesmortensen
注意,IE8不支持serializeArray。 - DigitalDesignDj

11
如果您不想使用外部库,可以使用本地JavaScript方法.toSource(),但它并不完全跨浏览器兼容。

11

在调用$.ajax之前,您应该对Json_PostData使用JSON.stringifyJSON.parse

$.ajax({
        url:    post_http_site,  
        type: "POST",         
        data:   JSON.parse(JSON.stringify(Json_PostData)),       
        cache: false,
        error: function (xhr, ajaxOptions, thrownError) {
            alert(" write json item, Ajax error! " + xhr.status + " error =" + thrownError + " xhr.responseText = " + xhr.responseText );    
        },
        success: function (data) {
            alert("write json item, Ajax  OK");

        } 
});

10

这基本上是一个2步骤的过程:

首先,您需要像这样进行字符串化:

var JSON_VAR = JSON.stringify(OBJECT_NAME, null, 2); 

接下来,您需要将 string 转换为 Object

var obj = JSON.parse(JSON_VAR);

10

最好的方法是包含JSON对象的polyfill。

但是,如果您坚持在jQuery命名空间中创建一个将对象序列化为JSON表示法(JSON的有效值)的方法,您可以像这样做:

实现

// This is a reference to JSON.stringify and provides a polyfill for old browsers.
// stringify serializes an object, array or primitive value and return it as JSON.
jQuery.stringify = (function ($) {
  var _PRIMITIVE, _OPEN, _CLOSE;
  if (window.JSON && typeof JSON.stringify === "function")
    return JSON.stringify;

  _PRIMITIVE = /string|number|boolean|null/;

  _OPEN = {
    object: "{",
    array: "["
  };

  _CLOSE = {
    object: "}",
    array: "]"
  };

  //actions to execute in each iteration
  function action(key, value) {
    var type = $.type(value),
      prop = "";

    //key is not an array index
    if (typeof key !== "number") {
      prop = '"' + key + '":';
    }
    if (type === "string") {
      prop += '"' + value + '"';
    } else if (_PRIMITIVE.test(type)) {
      prop += value;
    } else if (type === "array" || type === "object") {
      prop += toJson(value, type);
    } else return;
    this.push(prop);
  }

  //iterates over an object or array
  function each(obj, callback, thisArg) {
    for (var key in obj) {
      if (obj instanceof Array) key = +key;
      callback.call(thisArg, key, obj[key]);
    }
  }

  //generates the json
  function toJson(obj, type) {
    var items = [];
    each(obj, action, items);
    return _OPEN[type] + items.join(",") + _CLOSE[type];
  }

  //exported function that generates the json
  return function stringify(obj) {
    if (!arguments.length) return "";
    var type = $.type(obj);
    if (_PRIMITIVE.test(type))
      return (obj === null ? type : obj.toString());
    //obj is array or object
    return toJson(obj, type);
  }
}(jQuery));

用法

var myObject = {
    "0": null,
    "total-items": 10,
    "undefined-prop": void(0),
    sorted: true,
    images: ["bg-menu.png", "bg-body.jpg", [1, 2]],
    position: { //nested object literal
        "x": 40,
        "y": 300,
        offset: [{ top: 23 }]
    },
    onChange: function() { return !0 },
    pattern: /^bg-.+\.(?:png|jpe?g)$/i
};

var json = jQuery.stringify(myObject);
console.log(json);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接