参考にさせて頂いたページ
$httpサービスについて
$http | AngularJS 1.2 日本語リファレンス | js STUDIO
コントローラーの書き方について
jQueryとAngularJSにおけるAjaxの微妙な違い | ゆっくりと…
AngularJSでリクエストを送信すると$this->request->is('ajax')がfalseになってしまう事について
AngularJSのリクエストをPHPで処理するときのメモ - Qiita
runメソッドについて
AngularJS使い方ガイド Ajax編 | Webエンジニアブログ
その他
AngularJSのTutorialのstep-5よりAjaxの書き方・テストの仕方 - Qiita
ベースになるソースコード
以前書いた記事で、「jQueryを使用して・・・」を書いたのでこれをベースにAngularJSでもやってみる。
AngularJS1.4.7でsample.jsを書いてみる
「$http | AngularJS 1.2 日本語リファレンス | js STUDIO」のページの「概要 > 一般的な使用」を参考にjsを記述してみた。
具体的には以下の通り。
// myAppモジュールを作成 var app = angular.module('myApp', []); // myAppモジュールにSubmitCtrlコントローラーを登録 app.controller('SampleCtrl', ['$scope', '$http', function($scope, $http) { $scope.onclick = function(){ $http({method: 'GET', url: 'https://practice.mw.top/Ajax/find_contacts/'}) .success(function(data, status, headers, config) { // レスポンスが有効の場合に、非同期で呼び出されるコールバックです。 console.log(data); }) .error(function(data, status, headers, config) { // エラーが発生、またはサーバからエラーステータスが返された場合に、 // 非同期で呼び出されます。 console.log('error'); }); } }]);
以下のようなショートカットメソッドもある。
- $http.get
- $http.head
- $http.post
- $http.put
- $http.delete
- $http.jsonp
app/View/Contacts/index.ctp
jQueryでやったときのソースに以下のように追記した。
<button ng-controller="SampleCtrl" ng-click="onclick();">angular</button>
app/Controller/AjaxController.phpについて
$this->request->is('ajax')がfalseになってしまう事について
なぜfalseになるのかなんだけど、
「AngularJSのリクエストをPHPで処理するときのメモ - Qiita」のページの記事本文にある
XMLHttpRequestで判定しているのでAngularのリクエストではtrueになってくれません。
とか
コメントにある
X-Requested-With が削除された経緯らしきもの
とかによるものらしい。
「リクエストとレスポンスオブジェクト — CakePHP Cookbook 2.x ドキュメント」にも
is('ajax') 現在のリクエストが X-Requested-With = XMLHttpRequestに由来するものかどうかを調べます。
と書いてある。
代わりにどうやって判定するか
同じく「AngularJSのリクエストをPHPで処理するときのメモ - Qiita」のページにあるisAngular関数を定義して判定すると良いみたい。
その関数の内容としては、
ブラウザのアドレス入力によるリクエストなのか、AngularJSのHTTPリクエストなのか判定したい場合、$_SERVER['HTTP_ACCEPT']に「application/json」が含まれるかで判断すると良いです。
と書いてあります。
$_SERVER['HTTP_ACCEPT']には何が入っているのか
jQueryでリクエストを送ると"application/json, text/javascript, */*; q=0.01"が入っていた。
Angularでリクエストを送ると"application/json, text/plain, */*"が入っていた。
今回のAjaxController.phpの記述内容
<?php App::uses('AppController', 'Controller'); class AjaxController extends AppController { //使用するModel public $uses = array('Contact'); public function beforeFilter(){ parent::beforeFilter(); //ログインしていないときでも許可されているアクション (allow()はすべてのアクションを許可) $this->Auth->allow(array( 'find_contacts', )); } public function find_contacts() { //Ajaxでリクエストを送る為のアクションなので、Viewの描画を無効化 $this->autoRender = false; //関数を定義 function isAngular(){ if (false !== strpos($_SERVER['HTTP_ACCEPT'], 'application/json')) { return true; } return false; } //Ajax以外の通信の場合 if(!isAngular()) { //400 Bad Request エラー throw new BadRequestException(); } //contactsテーブルのデータを取得 $result = $this->Contact->find('all'); //値が入っているかを確認(trueまたはfalseが$statusに入る) $status = !empty($result); //データが無い場合は$errorにエラー内容を格納 if(!$status) { $error = array( 'message' => 'データがありません', 'code' => 404 ); } //$status,$result,$errorを結合して、JSON形式のデータを返す(js側で変数dataとして使用される) return json_encode(compact('status', 'result', 'error')); } }
URLバーに直に入力してページにアクセスしたとき$_SERVER['HTTP_ACCEPT']には何が入っているのか
ContactsController.phpのindexアクションで試してみたら、"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"が入っていた。
$_SERVER['HTTP_ACCEPT']とは
現在のリクエストの Accept: ヘッダがもしあれば その内容。
と書いてありました。
actionに引数を渡す
CakePHPなので、非同期通信の場合も以下のような感じで、アクション名に続いてスラッシュ区切りで渡せる。
https://hoge.com/コントローラー/アクション/hoge/foo/
非同期通信を使う際のセキュリティについて
$http | AngularJS 1.2 日本語リファレンス | js STUDIO
今回はここまで。