Ajax-вызов с contentType: "application/json" не работает
У меня есть вызов ajax, который отправляет данные формы в php-функцию. Поскольку я много читаю, что использование contentType: 'application/json'
- лучшая практика, я тоже хотел попробовать. Но, к сожалению, мой script ничего не возвращает, когда я его использую. Если я удалю его, script сделает то, что он должен делать.
Есть ли у вас какие-либо идеи, какова причина и почему? Спасибо!
$('#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));
}
Ответы
Ответ 1
При использовании contentType: 'application/json'
вы не сможете полагаться на заполненный $_POST
. $_POST
заполняется только для типов содержимого с кодировкой формы.
Таким образом, вам нужно прочитать свои данные из исходного ввода PHP следующим образом:
$input = file_get_contents('php://input');
$object = json_decode($input);
Конечно, если вы хотите отправить application/json
, вы действительно должны отправить JSON, который вы не делаете. Вам либо нужно напрямую построить сериализацию объекта в JSON, либо вам нужно сделать что-то вроде этого - Преобразовать данные формы в объект JavaScript с помощью jQuery - сериализовать объект из форма.
Честно говоря, в вашем случае, поскольку вы имеете дело с данными формы, я не совсем думаю, что используется прецедент для использования application/json
.
Ответ 2
Лучшей практикой, о которой вы говорите, является сервер script, устанавливающий Content-Type
для JSON в "application/json":
Header('Content-Type: application/json; charset=UTF8');
Это связано с тем, что в противном случае будет отправлено сообщение по умолчанию Content-Type
, чаще всего "catch-all" text/html
, и это может привести к непониманию с клиентом.
Если вы не указываете себе Content-Type в запросе jQuery, jQuery определит наиболее подходящий. Проблема здесь в том, что вы отправляете форму POST, для которой по умолчанию Content-Type
установлен jQuery is application/x-www-form-urlencoded
, который сообщает PHP, чтобы декодировать данные как поля POST и заполнить $_POST
. Тогда ваш script восстановил бы свои параметры от $_POST
(или, может быть, $_REQUEST
).
Изменив его на application/json
, $_POST
больше не будет заполнено, принимающая операция script не получит параметры, в которых она ожидала, и операция прерывается.
Итак, вам либо нужно:
- не указывать сам Content-Type (лучше, IMHO)
- установите тип содержимого
application/x-www-form-urlencoded; charset=UTF-8
- установить Content-Type
application/json; charset=UTF-8
и изменить script для анализа потока POST и декодирования данных JSON; см. этот ответ.
Третий вариант требует правильной обработки php://input
.
Ответ 3
PHP скрипт должен устанавливать заголовок Content-Type.
if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
header('Content-Type: application/json');
echo json_encode(validateForm($_POST));
}