CakePHP

CakePHP AjaxでJSONデータの出力の仕方とcontent-typeについて

以前、Ajax通信で結果を出力する際XMLデータだったので、Content-Typeを「application/xml」か「text /xml」にしようと、RequestHandlerのメソッド(setContent)をいろいろ試したのだが、いつも「text/html */*」となり、なかなか思うように出力できなかった。あの時は、クライアント側で支障なく利用できたので、放り出してしまった。

今回、クライアント側のJavaScriptで扱いやすいように、JSONでデータを出力することにしたので、前回クリアできなかったハードルに再 挑戦することとなった。と言っても、CakePHPについは世界中で多くの情報が公開されているため、作業は検索と動作チェックだけだったけど (^_^;)。

お題は、「ユーザ番号をAjaxのGETで渡し、DBのユーザ情報をJSONで出力する」という、簡単なお話し。クライアント側については、参考に後で掲載する。自分のような気の短い人のために、サーバ側CakePHPによる出力のサンプルを先に見る(^_^)。

controllers/users_controller.php

var $components = array('RequestHandler');
var $helpers = array('Html', 'Form', 'Javascript');

function beforeFilter() {
  if ($this->RequestHandler->isAjax()) {
    if ($this->action == 'getUserAjax') {
      Configure::write('debug', 0);
      $this->RequestHandler->setContent('json');
      $this->RequestHandler->respondAs('application/json; charset=UTF-8');
    }
  }
}

function getUserAjax($userid=0) {
  if (!$this->RequestHandler->isAjax()) {
    $this->cakeError('error404');
  }
  $user = $this->User->findById(intval($userid));
  $this->set('user', $user['User']);
}

views/users/get_user_ajax.ctp

<?php echo $javascript->object($user); ?>

Content-Typeを正しく出力するためには、「respondAs()」を「beforeFilter()」の中で実行しないといけない。今まで散々アクションの中で試していたので、うまくいかなかった訳だ(T_T)。

ところで、ブラウザ側では「text/html」で受け取っても特に問題なく動作する。が、Content-Typeが正しくセットされていない場合の脆弱性についての話しもあるので、ご注意を。あまり詳しくないので、機会があればGoogle先生に尋ねてみようと思う(^_^;)。

さて、クライアント側ではどのようにAjaxでリクエストしているかだが、HTMLのセレクトボックスでvalueにユーザ番号を持ち、セレクト ボックスに名前が表示されるデータを用意しておく。これは、CakePHPのfind(‘list’)を利用すれば簡単だ。Javascriptには、 「jQuery」を利用する。

以下、HTMLのJavascriptのソース

<script type="text/javascirpt" src="js/jquery.js"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
  $("#UserUserId").change(function() {
    $.get("/users/getUserAjax/"+$(this).val(), function(data) {
      var user = eval(data);
      $("#UserAddress").val(user.address);
          (その他必要な処理)
    });
  });
});
//]]>
</script>

と、こんな感じ。select要素にid=”UserUserId”の属性を持ち、option要素で指定されたユーザの名前を選択(changeイベント発生)したら、Ajax関数$.getにユーザ番号を付加したURLとコールバック関数を渡す。

Ajax通信が正常に終了すると、コールバック関数が実行されるので、その中でJSONのデータをevalを利用して、JavaScriptのオブ ジェクトに変換する。後は、HTML内のDOMにデータを埋め込む。例では、id=”UserAddress”を持つinput要素に読み出した住所を セットしている。

今回参考にさせていただいたサイトの記事です。ありがとうございました m(_ _)m。