Мне нужно сериализовать объект для JSON. Я использую jQuery. Есть ли «стандартный» способ сделать это?
Моя конкретная ситуация: у меня есть массив, определенный, как показано ниже:
var countries = new Array();
countries[0] = 'ga';
countries[1] = 'cd';
...
и мне нужно превратить это в строку для передачи $.ajax() следующим образом:
$.ajax({
type: "POST",
url: "Concessions.aspx/GetConcessions",
data: "{'countries':['ga','cd']}",
...
Да .. должен быть JSON.stringify ({страны: страны})
angular.js имеет: angular.fromJson и angular.toJson ... так что, если вы уже используете angular, что здорово, тогда woot



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не использовал его, но вы можете попробовать Плагин jQuery, написанный Марком Гибсоном
Он добавляет две функции: $.toJSON(value), $.parseJSON(json_str, [safe]).
В jQuery большинство хороших вещей поставляется в виде плагинов. Избегая плагинов, вы переписываете много уже написанного.
Обратите внимание, что $.parseJSON теперь находится в ядре jQuery.
Начиная с jQuery 3.0, $.parseJSON устарел. Вместо этого для анализа строк JSON используйте собственный метод JSON.parse.
Нет, стандартный способ сериализации в JSON - использовать существующую библиотеку сериализации JSON. Если вы не хотите этого делать, вам придется написать свои собственные методы сериализации.
Если вам нужны инструкции о том, как это сделать, я бы посоветовал изучить источник некоторых из доступных библиотек.
Обновлено: Я не собираюсь говорить, что писать собственные методы серляризации - это плохо, но вы должны принять во внимание, что если для вашего приложения важно использовать правильно сформированный JSON, тогда вам придется взвесить накладные расходы на «еще одну зависимость. "от возможности того, что ваши пользовательские методы однажды могут столкнуться с ошибкой, о которой вы не ожидали. Ваш вопрос, является ли такой риск приемлемым.
Писать собственный метод сериализации JSON - это плохо. Я сказал это. :-)
Делать то, что уже сделал кто-то другой, - плохо. Большинству из нас платят за выполнение работы, а не за изобретение колес.
Мне придется согласиться с @Adam по этому поводу. Он не рекомендует просто использовать свои собственные, но предлагает вам считать о том, какие зависимости вы принимаете, прежде чем просто принять это и «выполнить свою работу». Каждый раз, когда вы берете зависимость, вы полагаетесь на незафиксированную, не задействованную третью сторону, которая на самом деле не заботится о вашем проекте. Некоторые библиотеки хорошо документированы, хорошо поддерживаются здоровым сообществом, окружающим их, и обычно безопасны в использовании. Но в ваших интересах и интересах вашего клиента узнать об этом заранее.
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);
Недавно он был рекомендован Джон Ресиг:
...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. Текущая версия библиотеки JSON Крокфорда будет определять JSON.stringify и JSON.parse только в том случае, если они еще не определены, оставляя все нативные реализации браузера нетронутыми.
Хорошее замечание @ Mark0978. В качестве пояснения аргументы JSON.stringify объясняются здесь. Я еще не видел хорошего варианта использования второго параметра, но последний параметр весьма полезен: он указывает, сколько пробелов использовать для отступа при форматировании строки JSON.
Проверьте проблемы, прежде чем использовать это решение: [github.com/douglascrockford/JSON-js/pull/13] Возможно, безопаснее настроить этот код, создать некоторый объект JSON2 и использовать его независимо от поддержки JSON в браузере.
@pat, второй аргумент "replacer" очень полезен для настраиваемой сериализации известных объектов. Например, я сериализую элементы SVG, используя: JSON.stringify(obj, function(key, val) { if (val instanceof SVGSVGElement) {return val.xml || new XMLSerializer().serializeToString(val);} return val;})
Код Крокфорда не очень хорошо сочетался с некоторыми более сложными селекторами jQuery. Когда я закомментировал изменения Object.prototype внизу файла, все заработало, как и ожидалось.
На самом деле я предпочитаю JSON3. Он имеет поддержку AMD / requireJS и не использует eval, который сам Крокформ назвал «злом». github.com/bestiejs/json3
Если вы не хотите использовать внешние библиотеки, существует собственный метод JavaScript .toSource(), но он не является полностью кроссбраузерным.
Я где-то это нашел. Не могу вспомнить, где ... наверное, на 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;
};
Вы нашли это здесь: stackoverflow.com/questions/1184624/…
Фактически это не сериализует объект в строку JSON.
@pyrony - перейдите в веб-форму на веб-сайте, загрузите код JQuery в консоли FB и запустите это: var data = "" + $.toJSON($('form').serializeObject());. data теперь является строкой JSON. После этого запустите это: alert(typeof data); Он должен предупредить "строку". Затем запустите это: alert(data);, вы должны увидеть текст JSON. Наконец, перейдите к jsonlint.com и вставьте строку JSON. Он должен подтверждаться как Valid JSON. Я не уверен, что понимаю, что вы имеете в виду, поскольку все, кажется, указывает на создание действительного JSON. Еще раз спасибо.
У меня на сервере $.toJSON is not a function , поэтому я включил <script src = "http://www.x-non.com/json/jquery.json-2.4.min.js"> </script>
@ rubo77 - я точно не помню, зачем я использовал jquery-json. Это было опубликовано более 2-3 / 4 лет назад, и я думаю, что тогда было круто попытаться поддержать IE7 и IE6, в которых не было встроенного парсера JSON. Фактически вы можете заменить $.toJSON на JSON.stringify и получить тот же результат без внешних зависимостей, если вы поддерживаете только современные браузеры. Надеюсь это поможет! :)
Осторожно, IE8 не поддерживает serializeArray
Пользуюсь jquery-json 6 месяцев и отлично работает. Использовать очень просто:
var myObj = {foo: "bar", "baz": "wockaflockafliz"};
$.toJSON(myObj);
// Result: {"foo":"bar","baz":"wockaflockafliz"}
+1 Если вы уже используете jQuery, это лучший вариант. JSON-js великолепен как отдельная библиотека, но этот плагин легко интегрирует JSON.stringify и JSON.parse с jQuery. Это беспроигрышный вариант. ИМХО, это должен быть принятый ответ.
@EvanPlaice - Что значит «бесшовная интеграция». Что я получаю, используя jquery-json вместо JSON-js?
@ ripper234 Я имею в виду, что он использует собственные методы JSON.stringify / JSON.parse, если они доступны, в противном случае он вернется к своей собственной реализации. По сути, это полифилл для сериализации JSON. Преимущество заключается в том, что вы получаете сериализацию JSON на стороне клиента независимо от того, поддерживает ли ее изначально ваш пользовательский браузер.
Я искал замену IE6 JSON.stringify, и пока это единственный работающий. Я имею в виду, включение json.js вручную отлично работает, но конфликтует с пространством имен jQuery «$».
@EvanPlaice, jquery-json не является полифиллом. Это библиотека, которая использует собственные функции, если они доступны. Скорее, JSON-js (json2.js в частности) является полифилом, потому что он предоставляет тот же объект JSON и API-браузеры, что и браузеры API, но не убирает нативные функции (что означает, что современные браузеры по-прежнему получают высокопроизводительную нативную реализацию).
Нет необходимости в jQuery, используйте:
JSON.stringify(countries);
-1 Не будет работать в старых браузерах, в которых отсутствует встроенная сериализация JSON.
@Cory - просто включите JSON-js, который, если он будет найден, перейдет к нативной реализации.
Ага, согласился Джеймс. Пользуюсь таким же. Значение -1 связано с тем, что в этом ответе нет предупреждения о том, что вам нужно использовать библиотеку для поддержки старых браузеров.
Это не будет работать для всех браузеров: ---> Not compatible with IE 6,7
Я удалил предыдущее изменение и добавил его как комментарий, потому что он явно предназначался для комментария по проблеме.
@weltraumpirat - Ну, я добавил в другой редакции + ссылку на caniuse (перед прочтением вашего комментария). Я думаю, это важная часть ответа.
@ ripper234 Это может быть неотъемлемой частью решение, но разве это не особенность SO, чтобы каждый пользователь мог редактировать и / или добавлять дополнительную информацию к своему собственному ответу, чтобы улучшить его? OP будет уведомлен, когда будет опубликован комментарий ...
@weltraumpirat - SO - это вики. Если правка улучшает ответ, продолжайте и делайте это, не спрашивайте разрешения (вы также должны прокомментировать, чтобы уведомить владельца).
Взгляните на jquery-json. Он использует JSON.stringify, но предоставляет резервный метод, если он недоступен. Вот исходник code.google.com/p/jquery-json/source/browse/trunk/src/…
Кого волнует IE <8? Я не. Если бы я поступил по-своему, я бы даже не запрограммировал ни единого бита Javascript для любой его версии.
@ThomasEding Иногда выбора нет. У нас очень большое количество клиентов в Китае, которые, например, уйдут, если мы перестанем поддерживать IE6. Они являются сжимаются, но все еще существуют.
@Izkata: Я знаю. Мне просто нравится бить его ради удовольствия. Для личных проектов я бы не стал беспокоиться. Но в реальной работе я бы делал все, что хочет от меня начальник.
Одна вещь, которую вышеупомянутые решения не учитывают, - это то, что у вас есть массив входных данных, но было предоставлено только одно значение.
Например, если серверная часть ожидает массив людей, но в этом конкретном случае вы имеете дело только с одним человеком. Затем делаем:
<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;
};
Лучше всего включить полифил для объекта 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.info(json);
Это в основном двухэтапный процесс:
Во-первых, вам нужно сделать следующее:
var JSON_VAR = JSON.stringify(OBJECT_NAME, null, 2);
После этого вам нужно преобразовать string в Object:
var obj = JSON.parse(JSON_VAR);
Да, вы должны 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");
}
});
никто не указал, что
countries- это имя переменной, а не ключ ... эта информация будет потеряна, когда вы попытаетесь ее сериализовать.