可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has an answer here:
I need to serialize an object to JSON. I'm using jQuery. Is there a "standard" way to do this?
My specific situation: I have an array defined as shown below:
var countries = new Array(); countries[0] = 'ga'; countries[1] = 'cd'; ...
and I need to turn this into a string to pass to $.ajax()
like this:
$.ajax({ type: "POST", url: "Concessions.aspx/GetConcessions", data: "{'countries':['ga','cd']}", ...
回答1:
JSON-js - JSON in JavaScript.
To convert an object to a string, use JSON.stringify
:
var json_text = JSON.stringify(your_object, null, 2);
To convert a JSON string to object, use JSON.parse
:
var your_object = JSON.parse(json_text);
It was recently recommended by 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.
I tend to trust what he says on JavaScript matters :)
Newer browsers support the JSON object natively. The current version of Crockford's JSON library will only define JSON.stringify
and JSON.parse
if they're not already defined, leaving any browser native implementation intact.
回答2:
I've been using jquery-json for 6 months and it works great. It's very simple to use:
var myObj = {foo: "bar", "baz": "wockaflockafliz"}; $.toJSON(myObj); // Result: {"foo":"bar","baz":"wockaflockafliz"}
回答3:
Works on IE8+
No need for jQuery, use:
JSON.stringify(countries);
回答4:
I haven't used it but you might want to try the jQuery plugin written by Mark Gibson
It adds the two functions: $.toJSON(value)
, $.parseJSON(json_str, [safe])
.
回答5:
No, the standard way to serialize to JSON is to use an existing JSON serialization library. If you don't wish to do this, then you're going to have to write your own serialization methods.
If you want guidance on how to do this, I'd suggest examining the source of some of the available libraries.
EDIT: I'm not going to come out and say that writing your own serliazation methods is bad, but you must consider that if it's important to your application to use well-formed JSON, then you have to weigh the overhead of "one more dependency" against the possibility that your custom methods may one day encounter a failure case that you hadn't anticipated. Whether that risk is acceptable is your call.
回答6:
I did find this somewhere. Can't remember where though... probably on 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; };
回答7:
If you don't want to use external libraries there is .toSource()
native JavaScript method, but it's not perfectly cross-browser.
回答8:
The best way is to include the polyfill for JSON object.
But if you insist create a method for serializing an object to JSON notation (valid values for JSON) inside the jQuery namespace, you can do something like this:
Implementation
// 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));
Usage
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);
回答9:
Yes, you should JSON.stringify and JSON.parse your "Json_PostData" before calling $.ajax
$.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:
It's basically 2 step process:
First, you need to stringify like this
var JSON_VAR = JSON.stringify(OBJECT_NAME, null, 2);
After that, you need to convert the string to Object
var obj = JSON.parse(JSON_VAR);
回答11:
One thing that the above solutions don't take into account is if you have an array of inputs but only one value was supplied.
For instance, if the back end expects an array of People, but in this particular case, you are just dealing with a single person. Then doing:
<input type="hidden" name="People" value="Joe" />
Then with the previous solutions, it would just map to something like:
{ "People" : "Joe" }
But it should really map to
{ "People" : [ "Joe" ] }
To fix that, the input should look like:
<input type="hidden" name="People[]" value="Joe" />
And you would use the following function (based off of other solutions, but extended a bit)
$.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; };