Данные POST не отображаются в контроллере CakePHP
Я использую AJAX в форме knockout.js, чтобы опубликовать некоторую информацию, которую должен получить CakePHP, однако Cake, похоже, ничего не находит. Кроме того, предупреждение не появляется, несмотря на статус 200 (OK) из POST.
Здесь AJAX
$.ajax({
url: "/orders/finalize_payment",
type: "POST",
dataType: "json",
contentType: "json",
data: JSON.stringify({"customer": customer_id}),
success: function(){
alert("success");
}
});
Здесь соответствующее действие в контроллере заказов. Прямо сейчас я полностью раздели его до минимума.
function finalize_payment($id = null){
$this->layout = false;
$this->autoRender = false;
if($this->request->is('post')){ //the user has submitted which status to view
print_r($this->request->data);
echo "test"; //just to make sure it reaching this point
}
}
Когда я открываю вкладку сети в chrome, она показывает полезную нагрузку запроса как
customer: 1
POST показывает успех, статус 200. Я проверил заголовки ответов, и он просто показывает
array
(
)
test
Несмотря на то, что хром показывает отправку полезной нагрузки, CakePHP не находит ее, по-видимому.
Обновление
Я изменил запрос от AJAX на $.post, и он сработал. Я до сих пор не знаю, почему
$.post("/orders/finalize_payment",{"customer_id":customer_id},function(data){
alert('success');
});
Ответы
Ответ 1
Не кодировать почтовые данные как json
Код в вопросе не появится ни на одном php script, причина в следующем:
contentType: "json"
Это не запрос, закодированный форму-url, так, например, следующий код:
print_r($_POST);
print_r(file_get_contents('php://input'));
выведет:
Array()
'{"customer":123}'
Если вы хотите отправить данные как json, вам нужно прочитать необработанный объект запроса:
$data = json_decode(file_get_contents('php://input'));
Бывают случаи, когда это желательно (использование api), но это не обычный способ использования $.post
.
Нормальный путь
Обычный способ отправки данных - позволить jQuery позаботиться о кодировании для вас:
$.ajax({
url: "/orders/finalize_payment",
type: "POST",
dataType: "json", // this is optional - indicates the expected response format
data: {"customer": customer_id},
success: function(){
alert("success");
}
});
Это отправит данные сообщения как application/x-www-form-urlencoded
и будет доступна как $this->request->data
в контроллере.
Почему работает $.post
Я изменил запрос от AJAX на $.post, и он сработал. Я до сих пор не знаю, почему
Неявно с обновленным кодом в вопросе, который у вас есть:
- удален вызов JSON.stringify
- изменено с отправки json на отправку
application/x-www-form-urlencoded
Таким образом, это не то, что $.post
работает, а $.ajax
не ($.post
infact just calls $.ajax
) - это то, что параметры для результирующего вызова $.ajax
верны с синтаксисом в вопрос.
Ответ 2
Используя исходные данные и json, вы можете использовать:
$data = $this->request->input('json_decode');
** Данные - это объект, а не массив.
Затем вы можете использовать:
$this->MyModel->save($data).
Ответ 3
Замечательно отформатированный вопрос:)
Я уверен, что у меня есть ответ, хотя я мог ошибаться... В принципе, $this->request
- это объект в Cake, а $this->request->data
- это переменная/массив, являющийся свойством объекта.
Данные, которые вы отправляете в Cake, идут прямо в объект (если это возможно), а не в массив data
. Вот почему, когда Cake генерирует формы с использованием HtmlHelper, имена, например, data[User][username]
.
Я думаю, если вы поместите JSON.stringify({"customer": customer_id})
в массив 'data'
и отправьте его, он должен работать.
Ответ 4
Когда вы используете CakePHP, вы можете обнаружить, что добавление RequestHandler к вашим компонентам устраняет проблему.
public $components = array([snip], 'RequestHandler');
Это позволило мне прозрачно получить доступ к данным JSON, используя данные $this- > request- > . другие отвечают на рекомендации не кодировать данные POST, поскольку JSON становится немного неудобным, учитывая, что определенные JS-фреймворки, такие как Angular, отправляют JSON по умолчанию.
Ответ 5
Посмотрите этот пост. Вероятно, строка данных неверна. Поэтому CakePHP, возможно, не сможет помещать его в $this->request->data
.