Chcę służyć zawartości JSONP z CakePHP i zastanawiałem się, jaki jest właściwy sposób, aby to zrobić.Jaki jest właściwy sposób obsługi JSONP z CakePHP?
Obecnie mogę udostępniać zawartość JSON automatycznie, wykonując tę CakePHP guide.
Chcę służyć zawartości JSONP z CakePHP i zastanawiałem się, jaki jest właściwy sposób, aby to zrobić.Jaki jest właściwy sposób obsługi JSONP z CakePHP?
Obecnie mogę udostępniać zawartość JSON automatycznie, wykonując tę CakePHP guide.
ja jeszcze nie znalazłem kompletny przykład jak poprawnie powrót JSONP użyciu CakePHP 2, więc mam zamiar napisać go w dół. OP prosi o poprawną metodę, ale jego odpowiedź nie używa natywnych opcji dostępnych teraz w 2.4. Dla 2.4+, jest to właściwa metoda, prosto z ich dokumentacją:
Skonfiguruj swoje poglądy, aby zaakceptować/użycie JSON (documentation):
Router::parseExtensions('json');
do pliku routes.php
config. Mówi to ciasto, aby zaakceptować .json
URI rozszerzeńRequestHandler
do wykazu składników w kontrolerze masz zamiar używać/controller/action
(co byłoby użyć widoku w /view/controller/action.ctp
) lub/controller/action.json
(co byłoby użyć widoku w /view/controller/json/action.ctp
)Jeśli nie chcesz, aby określić te widoki czyli nie trzeba robić żadnych dalszego przetwarzania, a odpowiedź jest gotowy do pracy, można powiedzieć CakePHP ignorować poglądy i zwraca dane natychmiast za pomocą _serialize
. Użycie polecenia _serialize
spowoduje, że Cake sformatuje odpowiedź w poprawnym formacie (XML, JSON itd.), Ustaw nagłówki i zwróć je w razie potrzeby bez potrzeby wykonywania innych czynności (documentation). Aby skorzystać z tej magii:
$this->set('post', $post);
$this->set('_serialize', array('posts'));
, gdzie parametr jest zmienną widok po prostu ustawić w poprzedniej liniiI to wszystko. Wszystkie nagłówki i odpowiedzi zostaną przejęte przez Cake. To właśnie opuszcza jsonp dostać pracę (documentation):
$this->set('_jsonp', true);
, a ciasto będzie znaleźć nazwę parametru funkcji zwrotnej, a sformatuj odpowiedź, aby działała z tą nazwą funkcji zwrotnej. Dosłownie, ustawienie, że jeden parametr wykonuje całą pracę za Ciebie.Więc zakładając skonfigurowaniu ciasto przyjąć .json
żądań, to co to typowa akcja mogłaby wyglądać pracować jsonp:
public function getTheFirstPost()
$post = $this->Post->find('first');
$this->set(array(
'post' => $post, <-- Set the post in the view
'_serialize' => array('post'), <-- Tell cake to use that post
'_jsonp' => true <-- And wrap it in the callback function
)
);
a JS:
$.ajax({
url: "/controller/get-the-first-post.json",
context: document.body,
dataType: 'jsonp'
}).done(function (data) {
console.log(data);
});
Ok, znalazłem rozwiązanie na tym site. Zasadniczo zastępujesz metodę AfterFilter za pomocą:
public function afterFilter() {
parent::afterFilter();
if (empty($this->request->query['callback']) || $this->response->type() != 'application/json') {
return;
}
// jsonp response
App::uses('Sanitize', 'Utility');
$callbackFuncName = Sanitize::clean($this->request->query['callback']);
$out = $this->response->body();
$out = sprintf("%s(%s)", $callbackFuncName, $out);
$this->response->body($out);
}
Mam nadzieję, że pomoże to komuś innemu.
Dla CakePHP 2.4 i wyżej, możesz to zrobić zamiast tego.
http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#jsonp-response
więc można po prostu napisać:
$this->set('_jsonp', true);
w danym działaniu.
Albo można po prostu napisać:
/**
*
* beforeRender method
*
* @return void
*/
public function beforeRender() {
parent::beforeRender();
$this->set('_jsonp', true);
}
Od wersji Cake 2.4+ nie jest to już poprawny lub optymalny sposób obsługi żądań JSONP. Napisałem instrukcje, jak to zrobić, zgodnie z ich dokumentacją [poniżej] (http://stackoverflow.com/a/28963737/366529). – dKen