Данные 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.