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

6 мая, 2009
send json data

В прошлых статьях я рассказывал и приводил примеры получения и обработки данных в формате 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 коду.

  1. $(function() {
  2.     $("#myForm").submit(function() {
  3.         var formData = {
  4.             "field1":$("#field1").val()
  5.             , "field2":$("#field2").val()
  6.         };
  7.         $.ajax({
  8.             url:'dataparser.php'
  9.             , type:'POST'
  10.             , data:'jsonData=' + $.toJSON(formData)
  11.             , success: function(res) {
  12.                 alert(res);
  13.             }
  14.         });
  15.         return false;
  16.     });
  17. });

В этом примере я использовал библиотеку 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"}

Теперь рассмотрим серверный скрипт.

  1. <?php
  2. $data = json_decode($_POST['jsonData']);
  3. $response = 'Получено параметров '.count($data).'\n';
  4. foreach ($data as $key=>$value) {
  5.     $response .= 'Параметр: '.$key.'; Значение: '.$value.'\n';
  6. }
  7. echo $response;
  8. ?>

Я решил его сделать максимально простым, т.е. опустил все возможные проверки.

Чтение и преобразование данных выполняется одной строчкой кода (строка 2). В результате получаем массив ($data) с данными формы.

После этого скрипт формирует строку с этими же данными и отправляет её назад браузеру.

Как видите, пример получился довольно простой.

Если хотите поэкспериментировать с этим примером, качайте архив.

архив с исходным кодом

А если есть вопросы – пишите их в комментариях ;)

Понравилась статья? Подписывайтесь на продолжение rss link !

Или на мой твиттер twitter link

]]>

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

]]>

Опубликовано в Ajax, JavaScript, PHP, Web разработка Комментарии (40) »

]]>

Комментарии (40)

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

]]>
  1. Владимир, такой вопрос: зачем это нужно? К чему эти все лишние операции, когда передавать можно через стандартные массивы? Где это может на практике использоваться, реально понадобиться?

    • adw0rd

      Какие именно тут лишние операции? На фронтенде или бекенде?

      Если на фронтенде, то это вызвано синтаксисом JQuery, он может показаться избыточным, но тем не менее он очень гибок в использовании и функционален.

      Если на фронтенде, то тут как раз ничего лишнего нет… Банальный вывод в поток данных.

      Json по сути только на фронтенде надо формировать, на бекенде это js-объекты.

      • Так а какие преимущества даёт этот способ?

      • Лишние операции везде:
        на фронтенде – формирование json массива (+ использование дополнительного jQuery плагина)
        на бекенде – декодирование полученных данных.

        В чем "+", какие преимущества от этого всего?

        • Иван

          На сервере можно обойтись одной строкой – надо использовать библиотеки.
          На клиенте – я больше знаком с prototype, там это тоже делается одной строкой.
          Применение самое разное, но я чаще использую – сервер отдает json а яваскрипт обрабатывает и выводит, использую в custom контролах

    • Konstantin

      Добавлю, примеры, когда удобнее работать с JSON-ом. Допустим в вашем интерфейсе есть нестандартные элементы управления, например карта, на которой можно добавлять точки или выделять маршруты, или вы передаете на сервер результат сортировки элементов списка, или у вас есть грид ячейки которого можно редактировать.
      Формат очень гибкий и удобный, скорость работы с строками json_encode-decode в PHP нормальная. И еще с JSON-ом можно работать не стороне сервера не только на PHP, в NET 3.5 часть фреймворка, в JAVA тоже без проблемм. Ваш фронтэнд будет более гибкий.

      • Я попробую развить идею.
        Векторный online редактор. Координаты узлов кривых Безье можно сохранить в массиве и передавать его на сервер.
        В общем, везде, где нужно передавать многомерные массивы с данными удобнее JSON.

  2. Чистяков Денис

    По моему для отправки целой формы удобнее применять метод serialize() или serializeArray() для отправки в виде JSON'a.
    И субъективно:

    data: {
    jsonData: $.toJSON(formData)
    }

    приятнее выглядит, и удобнее для применения, чем

    data:'jsonData=' + $.toJSON(formData)

    так можно послать любое колличество параметров на бекэнд.
    А что бы потом не задумываться пришел нам POST или GET применять $_REQUEST ;)

  3. Я согласен, преимуществ этот метод не даёт, особенно если форма простая. И ситуаций когда приходилось бы им пользоваться у меня не возникало. Но недавно у меня спросили как это сделать и я решил опубликовать решение.

    Кроме того, есть реальные ситуации в которых этот метод может быть удобнее отправки формы обычным способом.

    Представьте, что есть форма в которой пользователь может менять количество поле и уровень их вложенности. Т.е. он создает структуру в виде дерева и заполняет ее данными. После этого отправляет её серверу.

    Если отправлять форму обычным способом, то придется передавать данные о родительских полях.
    А если сформировать на JS объект со всеми полями и отправить его в JSON формате, то на стороне сервера с помощью json_decode получим точно такой же объект.

    При этом сокращается количество кода на стороне сервера.

    2Чистяков Денис
    Большое спасибо за замечания, постараюсь учесть ;)

  4. Эдуард

    Не понимаю, почему, если сжимать ответ сервера
    <?php
    ob_start("ob_gzhandler");
    , то уже ни $.get, ни $.getJSON обработать его немогут…

    • Проведите небольшой эксперимент. Посмотрите ответ сервера с помощью firebug. Если вы видите кракозябры – значит браузер не понимает, что он получает сжатый ответ, исправляется отправкой соответствующих заголовков.
      Если видите нормальные буквы, проверьте формат ответа.

      • Эдуард

        Дело оказалось не в заголовках – убрал подпись Юникод (BOM) и заработало.

        • Мне тоже один раз BOM попортил настроение. Я пробовал какой-то из редакторов и пересохранил в нём скрипт, использующий сессии. О том, что тот редактор сохраняет с BOM я не знал и сразуже получил ошибку. Возился часа два, пока до меня дошло в чем дело.

  5. Артур

    Доброго времени. Почитал, разобрался, скачал пример, он не работает. Тестировался на сервере в инете, и на локальном сервере. Не распознается команда json_decode. А откуда вообще пхп скрипт может знать о такой функции?

  6. Александр

    Странно, но у меня пример тоже не работает.
    В alert'e выводит


    Warning: Invalid argument supplied for foreach() in dataparser.php on line 4
    Получено параметров 0\n

    PHP 5.2.1
    Json включен и работает

    • Если не сложно, сделайте скриншот firebug'ом (это плагин к Firefox).
      Похоже данные почему-то не передаются.
      Я только что скачал архив и перепроверил, у меня все нормально работает.

  7. Александр

    да что такое
    не отправить сообщение со ссылкой
    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)- работает с массивом

          foreach works only on arrays, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable

          Используйте приведение типов.

  8. Александр

    У меня в данном конкретном случае ничего не возвращает
    if (isset ($_POST["jsonData"])) {
    $post = $_POST["jsonData"];
    }
    //$post = {\"field1\": \"asd\", \"field2\": \"asd\"}
    $data = json_decode ($post);
    echo gettype($post); //выводит NULL

  9. Александр

    Всё, готово!
    Огромное спасибо Эдуарду!

    С костылями файл dataparser.php получился такой:
    $value) {
    $response .= "Параметр: ".$key."; Значение: ".$value."\n";
    }
    echo $response;
    ?>

  10. Александр

    Всё, готово!
    Огромное спасибо Эдуарду!

    С костылями файл dataparser.php получился такой:
    $value) {
    $response .= "Параметр: ".$key."; Значение: ".$value."\n";
    }
    echo $response;
    ?>

  11. Александр

    pastebin.com/f1d6fe319
    парсер ) ай-яй )

  12. dhj

    Все кто говорит что это лишнее кодирование ( см. первые посты) – на самом деле это самый простой и универсальный способ передавать структуры данных из любого фронтэнда к любому бекэнду. Гораздо проще передать один объект в формате json чем кучу пар "ключ-значение" которые потом надо еще как-то собрать воедино.
    PS: на этот пост набрел случайно – нужен был плагин для кодирование в json, желательно к jQuery. Саму статью не читал, так как все что там написано – достаточно просто, а вот комментарии – удивили.

    • Можно вопрос? Что должен делать плагин, который вы хотите найти? Преобразовать из хеша в json можно с помощью метода toJSON. А формирование самого хеша с данными – вопрос интересный. Сделать универсальный вариант с которым было бы удобно всем работать довольно сложно, но написать что-нибудь такое для себя – идея очень интересная.

  13. dhjj

    Вот как раз этот плагин и взял – мне в общем-то подошел. В боевом проекте используем jsHttpRequest от Дмитрия Котерова, а для себя искал что-нибудь попроще. По поводу формирования данных – все зависит от приложения – это личное дело каждого, все равно в бекэнде получишь нетипизированный объект или массив – но с ними гораздо проще работать, чем напрямую с GET или POST параметрами.

  14. Castro

    Чуть верю в жизнь не потерял, думал что-то с кешем.
    В файле лежит 3 функции вызова $.getJSON('getjson.php', {}, function(json){ ….
    Получается, что они выполняются не в том порядке, в котором лежат и а первыой выполяется та, в которой данных меньше и отрабатывает быстрее.
    Как сделать так, чтобы каждая следующи ajax вызов выполнялся после того, как отработает предыдущая функция?

    • Вызывать следующую в обработчике ответа предыдущей.

      $.getJSON('getjson.php', {}, function(json){
          $.getJSON('getjson2.php', {}, function(json) {
              $.getJSON('getjson3.php', {}, function(json) {});
          });
      });

      Как-то так.

  15. Всем привет.
    Вопрос. Когда передаю в свой же файл на своем же сервере все отлично передается
    jsonData{"username": "123", "password": "123", "request_type": "123"}

    Как только пытаюсь передать на сторонний сервер
    FireBug пишет уже не POST а OPTIONS json.

    http://kiwi-sms.ru/json/

    Подскажите если не сложно что делать.

  16. Владимир спасибо! Буду пробовать!

]]>

Оставить комментарий

* - обязательные для заполнения поля

]]>