2013-02-02 11 views

Odpowiedz

4

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ą:

  1. Skonfiguruj swoje poglądy, aby zaakceptować/użycie JSON (documentation):

    • Dodaj Router::parseExtensions('json'); do pliku routes.php config. Mówi to ciasto, aby zaakceptować .json URI rozszerzeń
    • Dodaj RequestHandler do wykazu składników w kontrolerze masz zamiar używać
    • Ciasto robi się tu mądry, a teraz oferuje różne widoki dla normalnych żądań i JSON/XML etc wnioski, dzięki czemu możesz elastycznie zwracać te wyniki, jeśli to konieczne. Teraz powinno być w stanie uzyskać dostęp do działania w kontrolerze przez:
      • pomocą URI /controller/action (co byłoby użyć widoku w /view/controller/action.ctp) lub
      • pomocą URI /controller/action.json (co byłoby użyć widoku w /view/controller/json/action.ctp)
  2. 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:

    • Ustawia zmienne, które chcesz zwrócić tak samo jak zmienną widoku, np.$this->set('post', $post);
    • Powiedz ciasto szeregować je w formacie XML, JSON itp wywołując $this->set('_serialize', array('posts'));, gdzie parametr jest zmienną widok po prostu ustawić w poprzedniej linii

I to wszystko. Wszystkie nagłówki i odpowiedzi zostaną przejęte przez Cake. To właśnie opuszcza jsonp dostać pracę (documentation):

  1. Powiedz ciasto do rozpatrzenia wniosku wniosek jsonp ustawiając $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); 
}); 
5

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.

+0

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

Powiązane problemy