Serializing to JSON in jQuery
我需要将对象序列化为JSON。我正在使用jquery。有没有一种"标准"的方法来做到这一点?
我的具体情况:我有一个数组定义如下:
1 2 3 4
| var countries = new Array();
countries[0] = 'ga';
countries[1] = 'cd';
... |
我需要把它变成一个字符串,这样传递给$.ajax():
1 2 3 4 5
| $.ajax({
type:"POST",
url:"Concessions.aspx/GetConcessions",
data:"{'countries':['ga','cd']}",
... |
- 没有人指出countries是一个变量的名称,而不是一个键…当您试图序列化它时,信息将丢失。
- 是啊。。需要是json.stringify(国家:国家)
- angular.js有:angular.fromjson和angular.tojson…所以,如果你已经在使用角度,这是可怕的,那么伍特
- stackoverflow.com/questions/38408348/…
JSON JS-JavaScript中的JSON。
要将对象转换为字符串,请使用JSON.stringify:
1
| var json_text = JSON.stringify(your_object, null, 2); |
要将JSON字符串转换为对象,请使用JSON.parse:
1
| var your_object = JSON.parse(json_text); |
John Resig最近建议:
...PLEASE start migrating
your JSON-using applications over to
Crockford's json2.js. It is fully
compatible with the ECMAScript 5
specification and gracefully degrades
if a native (faster!) implementation
exists.
In fact, I just landed a change in jQuery yesterday that utilizes the
JSON.parse method if it exists, now
that it has been completely specified.
我倾向于相信他在javascript上说的话:)
所有的现代浏览器(以及许多不古老的老浏览器)都支持本地的JSON对象。当前版本的crockford的json库只定义JSON.stringify和JSON.parse,如果它们还没有定义,那么任何浏览器本机实现都是完整的。
- 在mark0978处有一个很好的观点。通过解释,这里解释了json.stringify的参数。我还没有看到第二个参数的良好用例,但是最后一个参数非常有用:它指示格式化JSON字符串时要使用多少空格来缩进。
- 在使用此解决方案之前,请检查问题:[github.com/douglascorkford/json js/pull/13]也许更安全的方法是调整此代码,创建一些json2对象并使用它,而不管浏览器中是否支持json。
- @pat,第二个"replacer"参数对于定制已知对象的序列化非常有用。例如,我使用:JSON.stringify(obj, function(key, val) { if (val instanceof SVGSVGElement) {return val.xml || new XMLSerializer().serializeToString(val);} return val;})对svg元素进行序列化。
- Crockford的代码对一些更复杂的jquery选择器没有很好的效果。当我在文件底部注释了object.prototype修改时,它按预期工作。
- 我其实更喜欢JSON3。它有AMD/REQUIREJS支持,而且它不使用克罗克福尔姆自己称为"邪恶"的eval。github.com/bestiejs/json3
我已经使用jquery json 6个月了,它工作得很好。使用非常简单:
1 2 3 4
| var myObj = {foo:"bar","baz":"wockaflockafliz"};
$.toJSON(myObj);
// Result: {"foo":"bar","baz":"wockaflockafliz"} |
- +1如果您已经在使用jquery,那么这是一种方法。JSON JS作为一个独立的库非常好,但是这个插件将json.stringify和json.parse与jquery无缝集成。这是双赢。嗯,这应该是公认的答案。
- @"无接缝整合"是什么意思?在json-js上使用jquery-json会获得什么好处?
- @ripper234我的意思是它使用本机json.stringify/json.parse方法,如果它们可用,如果不可用,它将返回到它自己的实现中。基本上,它是用于JSON序列化的polyfill。好处是,无论用户的浏览器是否支持本地JSON序列化,您都可以获得客户端JSON序列化。
- 我一直在寻找一个ie6 json.stringify的替代品,这是迄今为止唯一能工作的。我的意思是,包括json.js手工工作很好,但是会与jquery"$"名称空间发生冲突。
- @jquery json不是polyfill。它是一个使用本机功能(如果可用)的库。相反,JSON JS(特别是JSON2.JS)是一个polyfill,因为它提供了相同的JSON对象和API浏览器提供的,但不会破坏本机功能(这意味着现代浏览器仍然获得高性能的本机实现)。
关于IE8+的作品
无需jquery,使用:
1
| JSON.stringify(countries); |
- -1无法在缺少本机JSON序列化的旧浏览器中工作。
- @CORY-只要包含JSON JS,如果找到它,就可以移交给本机实现。
- 是的,詹姆斯同意了。我也用同样的。-1是因为在这个答案中没有警告您必须使用库来获得对旧浏览器的支持。
- 这不适用于所有浏览器:---> Not compatible with IE 6,7。
- 我删除了以前的编辑,并将其添加为评论,因为它显然是为了评论这个问题。
- @Weltraumpirat——嗯,我用另一个词+链接添加到caniuse(在阅读你的评论之前)。我认为这是答案的一个重要部分。
- @Ripper234这可能是解决方案的一个重要部分,但让每个用户都成为编辑和/或在他/她自己的答案中添加更多信息以改进它的人,这难道不是重点吗?当一条评论被发布时会通知OP…
- @Weltraumpirat——维基也是。如果编辑改进了答案,请继续进行并使之成为答案,不要请求权限(您还应该评论以通知所有者)。
- 看看jquery json。它使用json.stringify,但如果不可用,则提供一个回退方法。这是源代码。google.com/p/jquery json/source/browse/trunk/src/…
- 谁在乎IE<8?我没有。如果我有办法的话,我甚至不会为它的任何版本编写一个单独的javascript。
- @托马斯丁有时别无选择。例如,如果我们停止支持IE6,我们在中国的客户数量将非常之多,令人不安。它们正在萎缩,但仍然存在。
- @伊兹卡塔:我知道。我只是喜欢为了好玩而敲打它。对于个人项目,我不会费心的。但对于实际的工作,我会做老板要我做的任何事情。
我没有用过,但你可能想试试马克·吉布森写的jquery插件。
它增加了两个功能:$.toJSON(value)、$.parseJSON(json_str, [safe])。
- 在jquery中,大多数好东西都是以插件的形式出现的。通过避免插件,您将重新编写许多已经编写的东西。
- 注意,$.parseJSON现在在jquery核心中。
不,序列化到JSON的标准方法是使用现有的JSON序列化库。如果您不想这样做,那么您必须编写自己的序列化方法。
如果您想了解如何执行此操作的指导,我建议您检查一些可用库的源代码。
编辑:我不会说编写自己的serliation方法是不好的,但是您必须考虑,如果使用格式良好的JSON对您的应用程序很重要,那么您必须权衡"再一次依赖"的开销,以防有一天您的自定义方法可能会遇到一个您没有预料到的失败案例。并入。风险是否可以接受是你的决定。
- 编写自己的JSON序列化方法是错误的。好了,我说了。-)
- 做别人已经做过的事是不好的。我们大多数人的报酬是完成工作,而不是重新发明轮子。
- 我必须同意@adam的观点。他并不是在鼓吹自己动手,而是建议你在接受它和"完成工作"之前,先考虑一下自己的依赖性。任何时候你依赖于一个不关心你的项目的、没有承诺的、没有参与的第三方。一些图书馆有良好的文档记录,周围有健康的社区,通常可以安全使用。但提前知道这一点符合你和你的客户的利益。
我在某个地方找到了这个。但不记得在哪里…可能在stackoverflow上:)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| $.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;
}; |
- 你在这里找到的:stackoverflow.com/questions/1184624/&hellip;
- 这实际上并没有将对象序列化为JSON字符串。
- @Pyrony-转到网站上的Web表单,在FB控制台中加载jquery代码,然后运行:var data ="" + $.toJSON($('form').serializeObject());。数据现在是一个JSON字符串。然后,运行这个:alert(typeof data);它应该警告"string"。然后运行这个:alert(data);,您应该会看到JSON文本。最后,转到jsonlint.com并粘贴到json字符串中。它应作为Valid JSON进行验证。我不确定我是否理解您的意思,因为所有的东西似乎都指向这个产生有效JSON的地方。再次感谢。
- 我的服务器上有$.toJSON is not a function ,所以我包括
如果不想使用外部库,可以使用.toSource()本机javascript方法,但它不是完全跨浏览器的。
是的,在调用$.ajax之前,应该先对json.stringify和json.parse您的"json-postdata"。
1 2 3 4 5 6 7 8 9 10 11 12 13
| $.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");
}
}); |
最好的方法是包含json对象的polyfill。
但是,如果您坚持在jquery名称空间内创建一个将对象序列化为json符号(json的有效值)的方法,您可以这样做:
实施
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| // 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)); |
用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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); |
基本上是两步过程:
首先,你需要像这样穿线
1
| var JSON_VAR = JSON.stringify(OBJECT_NAME, null, 2); |
之后,需要将字符串转换为对象
1
| var obj = JSON.parse(JSON_VAR); |
上述解决方案没有考虑的一件事是,如果您有一个输入数组,但只提供了一个值。
例如,如果后端需要一组人员,但在这种特殊情况下,您只需要处理一个人。然后做:
1
| <input type="hidden" name="People" value="Joe" /> |
然后,使用前面的解决方案,它只会映射到如下内容:
但它真的应该映射到
1 2 3
| {
"People" : ["Joe" ]
} |
要解决这个问题,输入应该如下所示:
1
| <input type="hidden" name="People[]" value="Joe" /> |
您将使用以下函数(基于其他解决方案,但扩展了一点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (this.name.substr(-2) =="[]"){
this.name = this.name.substr(0, this.name.length - 2);
o[this.name] = [];
}
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;
}; |