Сериализация в JSON в jQuery
Мне нужно сериализовать объект в JSON. Я использую JQuery. Есть ли "стандартный" способ сделать это?
Моя конкретная ситуация: у меня есть массив, определенный как показано ниже:
var countries = new Array();
countries[0] = 'ga';
countries[1] = 'cd';
...
и мне нужно превратить это в строку, чтобы передать $.ajax()
как это:
$.ajax({
type: "POST",
url: "Concessions.aspx/GetConcessions",
data: "{'countries':['ga','cd']}",
...
11 ответов
JSON- JS - JSON в JavaScript.
Чтобы преобразовать объект в строку, используйте JSON.stringify
:
var json_text = JSON.stringify(your_object, null, 2);
Чтобы преобразовать строку JSON в объект, используйте JSON.parse
:
var your_object = JSON.parse(json_text);
Недавно Джоном Резигом было рекомендовано:
... ПОЖАЛУЙСТА, начните перенос ваших приложений, использующих JSON, на json2.js Крокфорда. Он полностью совместим со спецификацией ECMAScript 5 и постепенно ухудшается, если существует собственная (более быстрая!) Реализация.
Фактически, я только что получил изменение в jQuery вчера, которое использует метод JSON.parse, если он существует, теперь, когда он полностью указан.
Я склонен доверять тому, что он говорит о JavaScript, имеет значение:)
Новые браузеры изначально поддерживают объект JSON. Текущая версия библиотеки JSON Крокфорда будет определять только JSON.stringify
а также JSON.parse
если они еще не определены, оставляя нетронутой любую реализацию браузера.
Я использую jquery-json в течение 6 месяцев, и он прекрасно работает. Это очень просто в использовании:
var myObj = {foo: "bar", "baz": "wockaflockafliz"};
$.toJSON(myObj);
// Result: {"foo":"bar","baz":"wockaflockafliz"}
Я не использовал его, но вы можете попробовать плагин jQuery, написанный Марком Гибсоном
Это добавляет две функции: $.toJSON(value)
, $.parseJSON(json_str, [safe])
,
Нет, стандартный способ сериализации в JSON - это использование существующей библиотеки сериализации JSON. Если вы не хотите этого делать, вам придется написать свои собственные методы сериализации.
Если вы хотите получить рекомендации о том, как это сделать, я бы посоветовал изучить источник некоторых из доступных библиотек.
РЕДАКТИРОВАТЬ: Я не собираюсь выходить и говорить, что написание ваших собственных методов serliaization является плохим, но вы должны учитывать, что если для вашего приложения важно использовать правильно сформированный JSON, то вы должны взвесить "еще один" зависимость от вероятности того, что ваши пользовательские методы могут однажды столкнуться со случаем сбоя, которого вы не ожидали. Приемлемый ли этот риск - ваш звонок.
Я где-то нашел это. Хотя не могу вспомнить, где... вероятно, на Stackru:)
$.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;
};
Если вы не хотите использовать внешние библиотеки, есть .toSource()
родной метод JavaScript, но он не идеально кросс-браузерный.
Да, вы должны JSON.stringify и JSON.parse ваши "Json_PostData" перед вызовом $.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");
}
});
Лучший способ - включить полифилл для объекта JSON.
Но если вы настаиваете на создании метода для сериализации объекта в нотацию JSON ( допустимые значения для JSON) внутри пространства имен jQuery, вы можете сделать что-то вроде этого:
Реализация
// 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);
Это в основном двухэтапный процесс:
Во-первых, вы должны привести в порядок, как это
var JSON_VAR = JSON.stringify(OBJECT_NAME, null, 2);
После этого вам нужно преобразовать строку в объект
var obj = JSON.parse(JSON_VAR);
Одна вещь, которую вышеупомянутые решения не принимают во внимание, - если у вас есть массив входных данных, но было предоставлено только одно значение.
Например, если серверная часть ожидает массив людей, но в данном конкретном случае вы имеете дело только с одним человеком. Затем делать:
<input type="hidden" name="People" value="Joe" />
Тогда с предыдущими решениями это просто отобразило бы что-то вроде:
{
"People" : "Joe"
}
Но это должно действительно отображаться в
{
"People" : [ "Joe" ]
}
Чтобы это исправить, входные данные должны выглядеть следующим образом:
<input type="hidden" name="People[]" value="Joe" />
И вы бы использовали следующую функцию (основанную на других решениях, но немного расширенную)
$.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;
};