Отправка данных в формате JSON с помощью JavaScript и jQuery

В прошлых статьях я рассказывал и приводил примеры получения и обработки данных в формате JSON на стороне клиента. Но примера отправки данных серверу в этом формате не было. Сегодня я попробую исправить это упущение.
Прежде всего, кратко напомню принцип передачи данных в JSON формате от сервера браузеру.
1) Серверный (PHP) скрипт формирует массив с данными, преобразует их в формат JSON (используется функция json_encode) и отправляет браузеру.
2) На стороне браузера JS скрипт обрабатывает полученные данные. Тут для преобразования данных используется eval.
То есть все преобразования данных сводятся к использованию двух функций.
Отправка данных серверу немного сложнее.
Прежде всего, нужно четко понимать, что отправить данные в формате JSON можно в параметрах запроса (GET или POST), т.е. точно также как и любые другие данные.
Т.к. формат JSON представляет собой обычную строку, то алгоритм отправки будет следующим.
1) Формируем JavaScript объект с данными, которые нужно отправить, например, со значениями, введенными пользователем в поля формы.
2) Преобразовываем этот объект в JSON формат.
3) Отправляем запрос серверу. В одном из параметров запроса передаем строку с JSON данными.
4) На стороне сервера читаем переданные данные (они придут в массиве $_GET или $_POST).
5) С помощью json_decode преобразуем JSON данные в массив.
Теперь рассмотрим небольшой пример.
Допустим, у нас есть страница с формой, которая содержит 2 поля: field1 и field2. Необходимо отправить эти данные в формате JSON серверному скрипту и прочитать его ответ.
Разметку формы я приводить не буду, она самая обычная и в конце статьи я дам ссылку на архив с примером.
Сразу перейдем к JavaScript коду.
-
$(function() {
-
$("#myForm").submit(function() {
-
var formData = {
-
"field1":$("#field1").val()
-
, "field2":$("#field2").val()
-
};
-
$.ajax({
-
url:'dataparser.php'
-
, type:'POST'
-
, data:'jsonData=' + $.toJSON(formData)
-
, success: function(res) {
-
alert(res);
-
}
-
});
-
return false;
-
});
-
});
В этом примере я использовал библиотеку jQuery и плагин jquery-json. Этот плагин значительно упрощает преобразование данных в JSON формат, т.е. сводит всю работу к вызову одного метода $.toJSON(...).
Рассмотрим подробнее этот пример.
Прежде всего, мы назначили обработчик события submit для формы. Обратите внимание, что этот обработчик возвращает false (строка 15). Таким образом, мы предотвращаем отправку данных формы обычным способом.
В строках 3-6 мы формируем JavaScript объект и заполняем его введенными в форму данными.
Затем отправляем AJAX запрос (строка 7). В параметре url указываем название PHP скрипта, который выполняет обработку данных. В параметре type – способ передачи данных.
Третий параметр (data) самый интересный. Здесь указываем имя параметра, в котором будут отправлены данные (jsonData), и сами данные (преобразуем JavaScript объект в JSON строку с помощью $.toJSON).
После этого, в параметре success указываем функцию, которая будет обрабатывать полученные данные.
В результате серверу будет отправлен только один параметр
jsonData {"field1": "111", "field2": "222"}
Теперь рассмотрим серверный скрипт.
-
<?php
-
$data = json_decode($_POST['jsonData']);
-
$response = 'Получено параметров '.count($data).'\n';
-
foreach ($data as $key=>$value) {
-
$response .= 'Параметр: '.$key.'; Значение: '.$value.'\n';
-
}
-
echo $response;
-
?>
Я решил его сделать максимально простым, т.е. опустил все возможные проверки.
Чтение и преобразование данных выполняется одной строчкой кода (строка 2). В результате получаем массив ($data) с данными формы.
После этого скрипт формирует строку с этими же данными и отправляет её назад браузеру.
Как видите, пример получился довольно простой.
Если хотите поэкспериментировать с этим примером, качайте архив.
А если есть вопросы – пишите их в комментариях
Понравилась статья? Подписывайтесь на продолжение
!
Опубликовано в Ajax, JavaScript, PHP, Web разработка Комментарии (40) »
Комментарии (40)
Вы можете отслеживать обсуждение записи с помощью RSS 2.0 ![]()
Вы также можете оставить комментарий, или трекбек с Вашего сайта.










Владимир, такой вопрос: зачем это нужно? К чему эти все лишние операции, когда передавать можно через стандартные массивы? Где это может на практике использоваться, реально понадобиться?
Какие именно тут лишние операции? На фронтенде или бекенде?
Если на фронтенде, то это вызвано синтаксисом JQuery, он может показаться избыточным, но тем не менее он очень гибок в использовании и функционален.
Если на фронтенде, то тут как раз ничего лишнего нет… Банальный вывод в поток данных.
Json по сути только на фронтенде надо формировать, на бекенде это js-объекты.
Так а какие преимущества даёт этот способ?
да, по сути мой вопрос сводился именно к этому.
Лишние операции везде:
на фронтенде – формирование json массива (+ использование дополнительного jQuery плагина)
на бекенде – декодирование полученных данных.
В чем "+", какие преимущества от этого всего?
На сервере можно обойтись одной строкой – надо использовать библиотеки.
На клиенте – я больше знаком с prototype, там это тоже делается одной строкой.
Применение самое разное, но я чаще использую – сервер отдает json а яваскрипт обрабатывает и выводит, использую в custom контролах
Добавлю, примеры, когда удобнее работать с JSON-ом. Допустим в вашем интерфейсе есть нестандартные элементы управления, например карта, на которой можно добавлять точки или выделять маршруты, или вы передаете на сервер результат сортировки элементов списка, или у вас есть грид ячейки которого можно редактировать.
Формат очень гибкий и удобный, скорость работы с строками json_encode-decode в PHP нормальная. И еще с JSON-ом можно работать не стороне сервера не только на PHP, в NET 3.5 часть фреймворка, в JAVA тоже без проблемм. Ваш фронтэнд будет более гибкий.
Я попробую развить идею.
Векторный online редактор. Координаты узлов кривых Безье можно сохранить в массиве и передавать его на сервер.
В общем, везде, где нужно передавать многомерные массивы с данными удобнее JSON.
По моему для отправки целой формы удобнее применять метод serialize() или serializeArray() для отправки в виде JSON'a.
И субъективно:
data: {
jsonData: $.toJSON(formData)
}
приятнее выглядит, и удобнее для применения, чем
data:'jsonData=' + $.toJSON(formData)
так можно послать любое колличество параметров на бекэнд.
А что бы потом не задумываться пришел нам POST или GET применять
$_REQUESTЯ согласен, преимуществ этот метод не даёт, особенно если форма простая. И ситуаций когда приходилось бы им пользоваться у меня не возникало. Но недавно у меня спросили как это сделать и я решил опубликовать решение.
Кроме того, есть реальные ситуации в которых этот метод может быть удобнее отправки формы обычным способом.
Представьте, что есть форма в которой пользователь может менять количество поле и уровень их вложенности. Т.е. он создает структуру в виде дерева и заполняет ее данными. После этого отправляет её серверу.
Если отправлять форму обычным способом, то придется передавать данные о родительских полях.
А если сформировать на JS объект со всеми полями и отправить его в JSON формате, то на стороне сервера с помощью json_decode получим точно такой же объект.
При этом сокращается количество кода на стороне сервера.
2Чистяков Денис
Большое спасибо за замечания, постараюсь учесть
Не понимаю, почему, если сжимать ответ сервера
<?php, то уже ни $.get, ни $.getJSON обработать его немогут…ob_start("ob_gzhandler");
Проведите небольшой эксперимент. Посмотрите ответ сервера с помощью firebug. Если вы видите кракозябры – значит браузер не понимает, что он получает сжатый ответ, исправляется отправкой соответствующих заголовков.
Если видите нормальные буквы, проверьте формат ответа.
Дело оказалось не в заголовках – убрал подпись Юникод (BOM) и заработало.
Мне тоже один раз BOM попортил настроение. Я пробовал какой-то из редакторов и пересохранил в нём скрипт, использующий сессии. О том, что тот редактор сохраняет с BOM я не знал и сразуже получил ошибку. Возился часа два, пока до меня дошло в чем дело.
Доброго времени. Почитал, разобрался, скачал пример, он не работает. Тестировался на сервере в инете, и на локальном сервере. Не распознается команда
json_decode. А откуда вообще пхп скрипт может знать о такой функции?Уважаемый, функция json_decode актуальна для php >= 5.2.0
http://ru2.php.net/json_decode
Посмотрите какая у вас версия.
Если версия младше, читайте комментарии
Странно, но у меня пример тоже не работает.
В alert'e выводит
Warning: Invalid argument supplied for foreach() in dataparser.php on line 4
Получено параметров 0\n
PHP 5.2.1
Json включен и работает
Если не сложно, сделайте скриншот firebug'ом (это плагин к Firefox).
Похоже данные почему-то не передаются.
Я только что скачал архив и перепроверил, у меня все нормально работает.
да что такое
не отправить сообщение со ссылкой
pic ipicture ru/uploads/091025/mUW2HyTNIy.png
Прошу прощения, я не объяснил, на что хотел взглянуть.
Нужен скриншот вкладки Console, после отправки формы с развернутой вкладкой post
Примерно так
http://screencast.com/t/H7LwZPm4LH
pic ipicture ru/uploads/091027/3IZuNfgPyl.png
менял register_globals на On – не помогло..
Спасибо, что помогаете )
json_decode проверял
скрипт
print_r(json_decode('[0,1]'));выдаёт
Array ( [0] => 0 [1] => 1 )Ага, тоже сталкивался с этой ошибкой
json_decode – возвращает mixed
foreach (array_expression as $value)- работает с массивом
Используйте приведение типов.
У меня в данном конкретном случае ничего не возвращает
if (isset ($_POST["jsonData"])) {
$post = $_POST["jsonData"];
}
//$post = {\"field1\": \"asd\", \"field2\": \"asd\"}
$data = json_decode ($post);
echo gettype($post); //выводит NULL
$data = (array) json_decode(stripslashes($_POST["jsonData"]));
Не обновлял страницу и не увидел Ваше сообщение
Спасибо!
Всё, готово!
Огромное спасибо Эдуарду!
С костылями файл dataparser.php получился такой:
$value) {$response .= "Параметр: ".$key."; Значение: ".$value."\n";
}
echo $response;
?>
Всё, готово!
Огромное спасибо Эдуарду!
С костылями файл dataparser.php получился такой:
$value) {
$response .= "Параметр: ".$key."; Значение: ".$value."\n";
}
echo $response;
?>
pastebin.com/f1d6fe319
парсер ) ай-яй )
Все кто говорит что это лишнее кодирование ( см. первые посты) – на самом деле это самый простой и универсальный способ передавать структуры данных из любого фронтэнда к любому бекэнду. Гораздо проще передать один объект в формате json чем кучу пар "ключ-значение" которые потом надо еще как-то собрать воедино.
PS: на этот пост набрел случайно – нужен был плагин для кодирование в json, желательно к jQuery. Саму статью не читал, так как все что там написано – достаточно просто, а вот комментарии – удивили.
Можно вопрос? Что должен делать плагин, который вы хотите найти? Преобразовать из хеша в json можно с помощью метода toJSON. А формирование самого хеша с данными – вопрос интересный. Сделать универсальный вариант с которым было бы удобно всем работать довольно сложно, но написать что-нибудь такое для себя – идея очень интересная.
Вот как раз этот плагин и взял – мне в общем-то подошел. В боевом проекте используем jsHttpRequest от Дмитрия Котерова, а для себя искал что-нибудь попроще. По поводу формирования данных – все зависит от приложения – это личное дело каждого, все равно в бекэнде получишь нетипизированный объект или массив – но с ними гораздо проще работать, чем напрямую с GET или POST параметрами.
Чуть верю в жизнь не потерял, думал что-то с кешем.
В файле лежит 3 функции вызова $.getJSON('getjson.php', {}, function(json){ ….
Получается, что они выполняются не в том порядке, в котором лежат и а первыой выполяется та, в которой данных меньше и отрабатывает быстрее.
Как сделать так, чтобы каждая следующи ajax вызов выполнялся после того, как отработает предыдущая функция?
Вызывать следующую в обработчике ответа предыдущей.
$.getJSON('getjson.php', {}, function(json){ $.getJSON('getjson2.php', {}, function(json) { $.getJSON('getjson3.php', {}, function(json) {}); }); });Как-то так.
Всем привет.
Вопрос. Когда передаю в свой же файл на своем же сервере все отлично передается
jsonData{"username": "123", "password": "123", "request_type": "123"}
Как только пытаюсь передать на сторонний сервер
FireBug пишет уже не POST а OPTIONS json.
http://kiwi-sms.ru/json/
Подскажите если не сложно что делать.
У меня FF этот запрос вообще не отправляет
И, по-идее, так и должно быть. Дело в том, что кросс-доменные (XSS) запросы запрещены разработчиками браузера (это часть политики безопасности). Т.е. вы можете отправить запрос только на тот сервер, с которого был загружен скрипт.
У меня было 3 поста на эту тему.
Как обойти запрет на XSS
XSS и Same Origin Policy
XSS с использованием JSONP и jQuery
Надеюсь, они вам помогут. Если будут вопросы или замечания, пишите, обсудим!
Если я не ошибаюсь то там или писать прокси на каком-то из языков программирования либо JSONP c колбеком
Точно.
Владимир спасибо! Буду пробовать!