OSC 東京で佐川 夫美雄さんのセッションでAngularJSが気になったので、AngularJSリファレンスを買って、勉強を始めました。AngularJSリファレンス自体は、AJAXに限らず、AngularJSの全般を紹介している本です。
AngularでAJAX
AngularでAJAXする方法ですが、$httpを使うとアクセスできます。以下のようなコードを書きます。今回は、シンプルに「情報を取得する」だけを行っています。
// app.js angular.module('app', []) .controller('SampleController', ['$scope', '$http', function ($scope, $http) { $http({ method: 'POST', url: 'http://example.com/wp-admin/admin-ajax.php', // 適宜変更する params: { action: 'ajaxsample', // 適宜変更する(*1) }, }) .success(function (data, status, headers, config) { $scope.message = data.title; // 適宜変更する }) .error(function (data, status, headers, config) { $scope.message = 'failed'; }); }]);
jQueryを使ったことがある方なら、さほど違和感なく実行できるのではないかな、と思います。
<!DOCTYPE html> <html lang="ja" ng-app="app" ng-strict-di> <head> <meta charset="utf-8"> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript" src="app.js"></script><!--上のjsコード--> </head> <body> <div ng-controller="SampleController"> <p ng-bind="message"></p> </div> </body> </html>
angular.jsは、各自ダウンロードをお願いします。私はAngularJSリファレンスのサンプルコードに同梱されているものを使いました。
app.jsは上に記述したスクリプトです。
WordPress側の実装
サーバー側はWordPressを使用しました。下記のようなコードを書きます。(テーマのfunctions.phpに書く、あるいはプラグインとして書いてください。)
add_action( 'wp_ajax_nopriv_ajaxsample', 'my_action_callback' ); function my_action_callback() { $data = array( 'title' => 'ajaxで返すデータ', // 適宜変更する ); wp_send_json($data); }
wp_ajax_nopriv_**** の **** の部分が、JSから呼び出すときのactionの部分(*1の箇所)になります。WordPress側のルールとしては、wp_ajax_nopriv_****だと、ログインしていない場合でもアクセスできます。ログインユーザーのみにする場合はwp_ajax_****という名前にします。
別ドメインからajax呼び出す場合
example.comに、WordPress
example.jpに、Angularで作ったページ
example.jpからexample.comのデータを取得する
という形で利用したい場合はどうすればよいでしょうか。デフォルトでは、別ドメインから呼び出すことはできなくなっています。別ドメインから呼び出し可能にするには、AJAXリクエストを受ける側のexample.comで
Access-Control-Allow-Origin: http://example.jp
というヘッダーを追加する必要があります。WordPressの場合は、
add_action( 'init', function() { header( "Access-Control-Allow-Origin: http://example.jp" ); });
と記述することで、別ドメインから呼び出し可能にできます。(自前でheader関数を呼び出していますが、もっと良い方法がありそうな気がします。設定するドメインを動的に指定する場合は、値を検証しないと意図しないヘッダーを出力してしまうかもしれませんのでご注意ください。)
AngularJSがエスケープを行ってくれる
上記の記述で、AngularJSがHTMLエスケープを行ってくれます。もし、エスケープしないで出力したい場合は、ngSanitizeというモジュールを追加した上で、ng-bind-htmlを使うようにしなければなりません。このため、不注意でエスケープ漏れ→クロスサイトスクリプティング脆弱性、というケースはかなり防げるのではないかな、と思います。JS側でデフォルトエスケープになっているのは嬉しいですね。
AngularJS自体は初めて触ったのですが、かなり使いやすそうな印象です。このぐらいの例だと、「jQueryで問題なく作れる」ですけど。