CORSはクロスサイト間のリソース管理。Javascriptから他のサイトのリソース取得を管理するためのプロトコル。
通常こういったクロスオリジンのアクセスは許されないが(ブラウザが許さない)サーバがあるhttpヘッダを返すことで許すことができる。
Access-Control-Allow-Origin
このヘッダを付けることで、クライアントはその値と自分のJSのサイトが一致していたら通信を許可する。.htaccessに以下のように記述すると、すべてのクロスオリジンアクセスを許す。
1 2 3 |
<IfModule mod_headers.c> Header add Access-Control-Allow-Origin "*" </IfModule> |
制限
通常は完全にアクセスを許すことはしたくないはずなので自分のサイトだけを登録するが、サイトが複数ある場合はデバッグ中のlocalhostを加えたい場合は面倒なことになる。
更にサイトがディレクトリを掘っていて、ディレクトリごとに.htaccessがある場合とかだっともっと複雑になる。
サイトが複数ある場合
とりあえず動いているものとして、以下の.htaccess。
1 2 3 4 5 6 |
<IfModule mod_headers.c> SetEnvIf Origin "^https?://(localhost:8080|tango\.dip\.jp)" AccessControlAllowOrigin=$0 Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin Header set Access-Control-Allow-Methods "GET,PUT,POST,DELETE" Header set Access-Control-Allow-Headers "Content-Type, Authorization" </IfModule> |
これはlocalhostとtango.dip.jpを許可する。返されるヘッダにはアクセス元のサイトのみが返るのだと思われる。
仕様によると以下の記述でもいいらしい。(試していない)
1 2 3 4 5 |
<IfModule mod_headers.c> Header set Access-Control-Allow-Origin "http://localhost:8080;http://tango.dip.jp" Header set Access-Control-Allow-Methods "GET,PUT,POST,DELETE" Header set Access-Control-Allow-Headers "Content-Type, Authorization" </IfModule> |
メソッド
上記の.htaccessにはメソッドの記述もあるが、これは許すメソッドを定義しているものと思われる。そのためにブラウザはOPTIONメソッドでリクエストしてこの情報を得るものと思われる。このときのURLはサイトのURLと同じと思われるので、PHPなどが動くときは200が返るようにしておかないと、Chromeなどはエラーを出す。OPTIONのときはPHPの$_POSTがないと思われるので、このとき500とかを返すとCORSがうまくいかない。
ChromeなどのエラーResponse to preflight request doesn’t pass access control checkはこのOPTIONを指しているものと思われる。
このように非常に面倒で、ヘッダとかを調べるのも面倒なので適当に書いた。ヘッダを確認するにはChromeのDEVTOOLSを使うといい。304になってしまう場合は、シフトキーを押しながらリロードするか、リロードボタンで右クリックして、ハードリロードなどを選ぶ。タイプコラムがxhrになっているのがスクリプトからのアクセス。