質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

5082閲覧

CakePHPでPreflight RequestでMissingControllerExceptionになる

HALBY

総合スコア16

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2017/06/22 11:49

編集2017/06/22 11:51

###前提・実現したいこと
CakePHPでREST APIを作り、AngularからHttp.getでデータを取得するプログラムを作っています

###発生している問題・エラーメッセージ
AuthorizationヘッダをくっつけてGETリクエストすると404 Not Foundになります

エラーメッセージ 2017-06-22 11:22:05 Error: [Cake\Routing\Exception\MissingControllerException] Controller class Users.json could not be found. Exception Attributes: array ( 'class' => 'Users.json', 'plugin' => false, 'prefix' => false, '_ext' => false, ) Request URL: /users.json Referer URL: http://localhost:4200/account

###該当のソースコード
一部抜粋

PHP

1// Routes.php 2Router::scope('/', function ($routes) { 3 $routes->extensions(['json']); 4 $routes->resources('Users'); 5}); 6 7// AppController 8class AppController extends Controller 9{ 10 public function initialize() 11 { 12 parent::initialize(); 13 14 $this->loadComponent('RequestHandler'); 15 $this->loadComponent('Flash'); 16 17 // CORS 18 $this->response->cors($this->request) 19 ->allowOrigin(['*']) 20 ->allowMethods(['GET', 'POST', 'OPTIONS']) 21 ->allowHeaders(['X-CSRF-Token, Authorization']) 22 ->allowCredentials() 23 ->exposeHeaders(['Link']) 24 ->maxAge(300) 25 ->build(); 26 } 27} 28 29// UsersController 30class UsersController extends AppController 31{ 32 public function index() 33 { 34 $users = $this->paginate($this->Users); 35 36 $this->set(compact('users')); 37 $this->set('_serialize', 'users'); 38 } 39}

TypeScript

1 private getServerData(user: firebase.User) { 2 user.getToken(true).then((token) => { 3 let headers = new Headers({ 4 'Authorization': 'Bearer ' + token, 5 }); 6 let options = new RequestOptions({ 7 headers: headers 8 }); 9 this.http.get( 10 'http://localhost:8765/users.json', 11 options 12 ).subscribe((res) => { 13 console.log(res); 14 }); 15 }); 16 }

###試したこと
以下の例では200が返ってきて成功します
・Authorizationヘッダなし
・Chromeを--disable-web-securityで起動しCORSを無効化した状態でリクエスト
・当該URLをアドレスバーで直接叩く
・アドレスから.jsonを取り払ってリクエスト

404 Not Foundになるのは
・localhost:8765/users""".json"""に
・Authorization: Bearer hogehogeをつけて
・プリフライトリクエスト(OPTIONSメソッド)が送信される状態
でリクエストしたときになります

###補足情報(言語/FW/ツール等のバージョンなど)
Angular 4
CakePHP 3.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

resources()が対応するメソッドに、 OPTIONS が含まれていないかもしれません
https://book.cakephp.org/3.0/en/development/routing.html#creating-restful-routes

★リクエストが成功する時

  1. /users.json というパターンに対応するRoutingを探す
  2. routesで「GET users.jsonusers/index」として「UsersController::index」と解釈
  3. 実行する

★リクエストが失敗する時

  1. /users.json というパターンに対応するRoutingを探す
  2. OPTIONSメソッドに対応する /users.json存在しない
  3. fallbackとして「Cakeの元々の規則に沿ったRouting」を探す
  4. /:controller/:action としての解釈なので、 第一階層 = users.json までを「コントローラー名」として解釈する
  5. 結果、「対応するコントローラーがない」エラーになる

のかな・・?と思いました。
※たぶん、 routes.phpの中にて $routes->fallbacks()を読んでいますよね‥?

対応策としては、

  1. Routingの設定 or Middleware layerで「OPTIONSでのリクエストを拾えるようにする」
  2. 「OPTIONSでのリクエストの時に、結果を返せるようにする」

というものになるでしょうか。

今手元でコードを読んだり検証したりができていないので、↑の内容はもしかしたら齟齬がある・・かもしれないのですが、
こちらの回答などは「たぶん大丈夫そう?」と思ったので、よろしければお試しください。
https://stackoverflow.com/questions/39365229/cakephp-3-rest-api-cors-request-and-options-method

投稿2017/06/22 17:20

o0h

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HALBY

2017/06/23 01:21

回答ありがとうございます! StackOverflowのその回答のコードは前に試してみたのですが、同じエラーを吐いてしまいます beforeFilterにたどり着く前に例外を投げてしまうようです
HALBY

2017/06/23 01:28 編集

Stack Traceはこんな感じです #0 ~(略)~/vendor/cakephp/cakephp/src/Http/ControllerFactory.php(65): Cake\Http\ControllerFactory->missingController(Object(Cake\Http\ServerRequest)) #1 ~(略)~/vendor/cakephp/cakephp/src/Http/ActionDispatcher.php(90): Cake\Http\ControllerFactory->create(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #2 ~(略)~/vendor/cakephp/cakephp/src/Http/BaseApplication.php(78): Cake\Http\ActionDispatcher->dispatch(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #3 ~(略)~/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Http\BaseApplication->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner)) #4 ~(略)~/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php(59): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #5 ~(略)~/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Routing\Middleware\RoutingMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner)) #6 ~(略)~/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php(93): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #7 ~(略)~/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Routing\Middleware\AssetMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner)) #8 ~(略)~/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php(92): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #9 ~(略)~/vendor/cakephp/cakephp/src/Http/Runner.php(65): Cake\Error\Middleware\ErrorHandlerMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner)) #10 ~(略)~/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php(52): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #11 ~(略)~/vendor/cakephp/cakephp/src/Http/Runner.php(65): DebugKit\Middleware\DebugKitMiddleware->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response), Object(Cake\Http\Runner)) #12 ~(略)~/vendor/cakephp/cakephp/src/Http/Runner.php(51): Cake\Http\Runner->__invoke(Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #13 ~(略)~/vendor/cakephp/cakephp/src/Http/Server.php(80): Cake\Http\Runner->run(Object(Cake\Http\MiddlewareQueue), Object(Cake\Http\ServerRequest), Object(Cake\Http\Response)) #14 ~(略)~/webroot/index.php(37): Cake\Http\Server->run() #15 {main}
o0h

2017/06/23 03:19

やはり、 `「OPTIONSでのリクエストを拾えるようにする」` の辺りの問題かと思いますね。 「OPTIONSで来た時に、対応するコントローラーが見つからない」ので 「コントローラーを起動できない」 = 「beforeFIlterより前に」になるかと思います。 ### ざっくばらんにやるなら 1. OPTIONSリクエストを受け取れるようにする ```php // routes.phpの修正 Router::scope('/', function ($routes) { $routes->extensions(['json']); $routes->resources('Users', [ 'map' => [ 'options' => ['action' => 'options', 'method' => 'OPTIONS', 'path' => ''], ] ]); }); ``` 2. OPTIONSを捌けるようにメソッドを生やす ```php // AppController public function options() { if ($this->request->is('options')) { return $this->response; } } ``` こうすることで、 1. `OPTIONS users.json`のリクエストも捌いて、コントローラーを起動できるようになり 2. 対応アクションとして `AppController::options()`が呼び出されるようになる ので、件のエラーは解消するかと思います。 ※ CORS用の出力については、こちらの内容も参照してみてください。 https://book.cakephp.org/3.0/ja/controllers/request-response.html#cors ### 丁寧目にやるなら https://github.com/ozee31/cakephp-cors を利用します。 このプラグインの場合、「Middlewareレイヤーを利用する」という方法を採用しています (Middlewareについては [コチラ](https://book.cakephp.org/3.0/ja/controllers/middleware.html) --- ちなみに、私の関わっているPJでは「(自前で実装した)MiddlewareでCORSを捌く」方法を利用していて、処理も簡潔になるため、このやり方の方がオススメです^^
HALBY

2017/06/23 04:05

このプラグインで一発で解決しました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問