Вызов Ajax с contentType: "application/json" не работает

у меня есть вызов ajax, который отправляет данные формы в функцию php. Так как я много читал, используя contentType: 'application/json' лучшая практика, которую я хотел бы попробовать. Но, к сожалению, мой сценарий ничего не возвращает, когда я его использую. Если я удалю его, скрипт сделает то, что он должен сделать.

у вас есть какие-либо идеи, в чем может быть причина и почему? Спасибо!

$('#Form').submit(function(e) {
            e.preventDefault();

            var content = $(this).serialize() + "&ajax=1";

            $.ajax('app/class/controller/contactForm.php', {
              type: "POST",
              //contentType: 'application/json',
              dataType: 'json',
              data: content,
              success: function(result) {
                  console.log(result);
              }
            });
        })

и мой PHP:

if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
    echo json_encode(validateForm($_POST));
}

3 ответов


при использовании contentType: 'application/json' вы не сможете положиться на $_POST заполняется. $_POST заполняется только для типов содержимого, закодированных в форме.

таким образом, вам нужно прочитать ваши данные из PHP raw input следующим образом:

$input = file_get_contents('php://input');
$object = json_decode($input);

конечно, если вы хотите, чтобы отправить application/json вы действительно должны отправить JSON, чего вы не делаете. Вам либо нужно построить сериализацию объекта непосредственно в JSON, либо вам нужно сделать что - то вроде этого -преобразование данных формы Объект JavaScript с jQuery - для сериализации объекта из формы.

честно говоря, в вашем случае, поскольку вы имеете дело с данными форма, я не думаю, что в случае использования application/json есть.


лучшая практика, на которую вы ссылаетесь, - этосервер скрипт задание Content-Type для JSON в "application/json":

Header('Content-Type: application/json; charset=UTF8');

это потому, что в противном случае по умолчанию Content-Type будет отправлен, часто catch-all text/html, а это может привести к непониманию с клиентом.

если у вас не укажите себе тип контента в запросе jQuery, jQuery определит наиболее подходящий. Проблема в том, что ты посылали поста, для которого значение по умолчанию Content-Type установлен jQuery is application/x-www-form-urlencoded, который говорит PHP декодировать данные как поля POST и заполнить $_POST. Затем ваш скрипт восстановил бы свои параметры из $_POST (или $_REQUEST).

изменив его на application/json, $_POST больше не будет заполняться, операция принимающего скрипта не будет получать параметры, где она ожидала, и операция разрыв.

поэтому вам либо нужно:

  • не указывайте контент-тип самостоятельно (лучше, ИМХО)
  • Установите тип контента application/x-www-form-urlencoded; charset=UTF-8
  • Установите тип контента application/json; charset=UTF-8 и измените скрипт для анализа потока POST и декодирования данных JSON; см. ответ.

третий вариант требует правильное обращение of php://input.


PHP-скрипт должен устанавливать заголовок Content-Type.

if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
    header('Content-Type: application/json');
    echo json_encode(validateForm($_POST));
}