Ajax は、クライアント側(JavaScript)コードからサーバー側に(通常非同期で)アクセスするものです。
Ajax は、ページ自体を読み込み直さないので、 変更したいデータだけをサーバーから取得できること(部分的な表示の変更や通信データ量の軽減)や、 クライアント側の細かなイベントに合わせてサーバーにアクセスできる使い勝手の良さもあり、 ユーザーにサーバーにアクセスしている感覚をなくすことで、 使い勝手が向上するメリットがあります。
SyLフレームワークで、Ajax + JSON を行うには、下記の手順を行います。
(1) サーバー側で、Ajax ライブラリを出力するPHPコードを記述
(2) クライアント側で、Ajax ライブラリをインポート
(3) クライアント側で、Ajax リクエストするJava Scriptコードを記述
(4) サーバー側で、JSON 出力するPHPコードを記述
(5) クライアント側で、JSON 出力を受け取るコールバック関数を記述
(1) サーバー側で、Ajax ライブラリを出力するPHPコードを記述
Ajax 通信を行うには、まず通信を行うライブラリをインポートします。 ここでは、インポートするための Ajax ライブラリを出力するサーバー側の処理を説明します。
もし、JavaScript出力フレームワークを使用しているのであれば、外部パラメータから読み込めるので、ここは省略可能です。 WEBアプリケーションフレームワークのみで作成する場合は、下記のように直接アクションで 動的にJavaScript出力ビューに切り替え、 Ajax ライブラリを出力します。
function execute(&$data, &$context) { $context->setViewType('js.default'); $data->addImport('ajax'); }
(2) クライアント側で、Ajax ライブラリをインポート
(1)で作成したサーバー側のファイルを HTML のスクリプトタグで読み込みます。
スクリプトタグの記述例) <script type="text/javascript"
src="/web_controller.php/ajax.html"></script>
JavaScript出力フレームワークを使用している場合は、(1)を行わなくてもアクションがマッピングされていないURLに対して下記のように記述することにより自動的にインポートできます。
スクリプトタグの記述例) <script type="text/javascript"
src="/js_controller.php/index.js?import=ajax"></script>
※ここでインポートする Ajax ライブラリは、SYL_INCLUDE_DIR /lib/JsClient/SyL_JsClientAjax.js となり、上記方法ではこれを直接インポートしています。
(3) クライアント側で、Ajax リクエストするJavaScriptコードを記述
(2)のインポートで取得したライブラリのメソッドを使用して、サーバー側にアクセスするJavaScriptコードを記述します。
SyL.Ajax.Request.sendAsyncPost('/js_controller.php/ajax/getserver.js',
"js_client_method", {'ext_parameter': 'js_param'});
SyL.Ajax.Request.sendAsyncPost メソッドは、POST非同期通信で、サーバーにアクセスするメソッドです。パラメータはそれぞれ、下記のようになります。
引数 | 型 | 必須 | 内容 |
---|---|---|---|
第1引数 | string | ○ | サーバー側から JSON 出力を行うリクエストURI。(4)参照。 |
第2引数 | function string |
○ | サーバー側処理後、JSON 出力を引数とするクライアント側コールバックメソッド。JSONPの場合はstringで指定する。(5)参照。 |
第3引数 | object | - | サーバー側に送信する追加引数 |
(4) サーバー側で、JSON 出力するPHPコードを記述
(3)の第1引数で指定したURLが実行するアクションに対し処理を実装します。
アクション内の任意処理後、JavaScript側に渡すパラメータをセットして、出力するビュータイプを json に変更します。
routers.xml でデフォルトビューを json に変更することにより、透過的な json ビューを使用することも可能です。
function execute(&$data, &$context) { $data->set('serverdata', 'Hello Ajax!'); $context->setViewType('json'); }
※JavaScript出力フレームワークを使用しない場合は、パラメータのエンコーディングを適切に変更してください。
(5) クライアント側で、JSON 出力を受け取るコールバック関数を記述
(3)の第3引数で指定したコールバック関数を json データを引数に実装します。
<script type="text/javascript"> function js_client_method(json) { alert(json['serverdata']); } </script>
1. の使用方法で使用したのは、sendAsyncPost メソッドです。 これは、POSTで非同期送信を行うためのメソッドですが、GETや同期送信を行うためのメソッドも用意されています。 (引数の内容は、sendAsyncPost メソッドと同じです)
GET送信だとブラウザにキャッシュされやすいことや、同期だとサーバーからデータを取得するまで、プログラムを待機させられます。
メソッド | GET/POST | 同期/非同期 |
---|---|---|
SyL.Ajax.Request.sendAsyncGet | GET | 非同期 |
SyL.Ajax.Request.sendSyncGet | GET | 同期 |
SyL.Ajax.Request.sendAsyncPost | POST | 非同期 |
SyL.Ajax.Request.sendSyncPost | POST | 同期 |
XMLHTTP オブジェクトを使用した Ajax 通信では、クロスドメイン間のリクエストができない仕様上の制限があります。 JSONP では、JavaScript 内で動的に SCRIPT タグを作成し外部ファイルをロードすることにより、 クロスドメインでも通信が可能になります。
SyLフレームワークでは Ajax + JSON と JSONP の通信は、同様の手順で使用ます。 2. で紹介したメソッドの引数の内容の違いにより、Ajax + JSON か JSONP か判断されます。
JSONP通信の条件
2. で紹介したメソッドの第1引数の URL が、http:// 、https:// 、// のいづれかで始まるとJSONPとして通信するようになります。 ただし、第3引数のコールバックメソッドを必ず string で指定してください。
また、リクエストを受けるサーバー側のビュータイプも JSONP に変更します。
function execute(&$data, &$context)
{
$data->set('serverdata', 'Hello Ajax!');
$context->setViewType('jsonp');
}
JSONP の POST 通信
JSONP は、通常 SCRIPT タグで読み込む性質上、GET リクエストしかできません。 SyLフレームワークでは、JSONP で POST リクエストが指定された場合、SCRIPT タグの代わりに IFRAME タグを動的に作成し、IFRAME側に POST することで、 リクエスト結果は、IFRAME 内の SCRIPT タグから コールバックメソッドが起動する形になっています。