クロスドメイン問題を回避した時のメモ
今の業務ではフロントエンドアプリケーションとバックエンド API 用で分けて開発しています。 フロントエンドアプリケーションはサーバーレスにする予定です。 動作確認のために一々デプロイするのは面倒なため、バックエンドサーバーの設定を変えてクロスオリジン通信を許可したメモです。
* バックエンドサーバーの nginx の設定ファイルを編集して適切なロケーションディレクティブにレスポンスヘッダを追加
location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since'; add_header 'Access-Control-Allow-Methods' 'GET, DELETE, OPTIONS, POST, PUT'; add_header 'Access-Control-Allow-Origin' 'http://example.com'; add_header 'Access-Control-Max-Age' 2592000; add_header 'Content-Length' 0; add_header 'Content-Type' 'text/plain charset=UTF-8'; return 204; } add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'Content-Type, Accept'; }
- 設定反映のため、nginx 再起動
nginx -s reload
- バックエンドサーバーにリクエストを送り、レスポンスを確認。
# -I : HTTP レスポンスヘッダを表示 curl -I https://[site-url] # 設定したレスポンスヘッダが確認出来れば OK Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true Access-Control-Allow-Method: GET, POST, OPTIONS, PUT, DELETE Access-Control-Allow-Headers: Content-Type, Accept
- nginx 設定ファイルが間違っている場合はシンタックスチェックしながら修正
nginx -t -c /path/nginx.conf
- nginx 設定補足
if ($request_method = 'OPTIONS') {
HTTP DELETE メソッドなどのリソースを変更する可能性のあるリクエストを送る場合、ブラウザはまずプリフライトリクエストを HTTP OPTIONS メソッドで送信します。
add_header 'Access-Control-Max-Age' 2592000;
プリフライトリクエストを毎回送らなくて良いように、プリフライトリクエストのレスポンスをブラウザでキャッシュして良い時間。
この例では 60 (秒) x 60 (分) x 24 (時間) x 30 (日) で 30 日間です。
実際にはブラウザ毎に設定されている上限値になります。
add_header 'Access-Control-Allow-Origin' '*' always;
always パラメータを指定しておくと、4XX 、5XX の HTTP ステータスコードだった場合でもヘッダ情報を付加してくれます。
- ハマったところ
設定するロケーションディレクティブが間違っていた。 ロケーションディレクティブは読み込む優先順位があって、上に書いてあるから読み込まれる訳ではなかった。