WEBサービスを開発する際に、バックエンドはAPIサーバーとして稼働させてフロントエンドと分ける下記のようなアーキテクチャを採用した時にハマったことについて書いていきます。(二度と同じ轍を踏まないように!)
---------- ----------- ------------
| | | | | |
| |-------------->| Nginx |-------------->| |
| Client | | Reverse | | API Server |
| |<--------------| Proxy |<--------------| |
| | | | | |
---------- ----------- ------------
ハマったこと
CORS(Cross-Origin Resource Sharing)を許可するためにNginxでヘッダーを挿入するように設定をしていました。
add_header Access-Control-Allow-Origin https://trouble.example.jp;
APIサーバーから正常系(HTTPステータスコード200・300番系)のレスポンスが返された時はクライアント側と正常に通信していました。
しかし、APIサーバーから異常系(HTTPステータスコード400・500番系)のレスポンスが返された時にクライアント側でCORSエラーが発生しました。
当初は、正常系の通信はできていたのでフロントエンドを疑っていました。
しかし、調査していくと異常系のレスポンス時にはCORSを許可するためのAccess-Control-Allow-Origin
がHTTPヘッダーに挿入されていなことが分かり、バックエンドに原因があると判断しました。
解決方法
Access-Control-Allow-Origin
の設定行にalways
というキーワードを追記するだけで解決しました。
add_header Access-Control-Allow-Origin https://trouble.example.jp always;
Nginxの公式ドキュメントでしっかり説明されていました。
Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). Parameter value can contain variables.
If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.
正常系(HTTPステータスコード200・300番系)のレスポンスの場合は指定されたヘッダーが挿入されますが、それ以外のステータスコードでは挿入されません。
なので、ステータスコードに関わらずヘッダーを挿入したい場合はalwaysを指定する必要があるようでした。
「公式ドキュメントはちゃんと読みましょう」ということですね