TL;DR
expressの設定app.all( '/*', function( req, res, next ){
の中身は、res.setHeader( 'Access-Control-Allow-Origin', * );
だけでは足りなかった。以下を追加したらCORSのエラーが消えて正常に通信できた。
res.setHeader( 'Access-Control-Allow-Methods', '*' );
res.setHeader( 'Access-Control-Allow-Headers', '*' );
経緯
PostgreSQLを用いたDBサーバーに対して、Node.jsでアプリケーションサーバー(DBへのAPIとユーザーへの表示を兼ねたサーバー)を作っていました。expressを用いたDBへのCRUDが完成し、UIにこだわりたくなったため、フロントエンドフレームワーク(React)を用いてリッチな表示を試そうとしました。アプリケーションサーバー側のUI機能を一旦止めて、REST APIサーバーとして扱わせることに。
React側でAPIサーバーと通信したかった
React側でaxiosを用いてAPIリクエスト(GET)を送ってみるとデータは正しく取り出せた。
じゃあPOSTしてみよう。
適当にフォームを作ってaxiosでPOSTリクエストを書いて送ってみると…
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:2501/api/db/person. (Reason: CORS request did not succeed). Status code: (null).
CORSで許可されてないと怒られた。ん??
CORS許可されてなかったらなんでGETはできるんだ?
setting_cors = *; // 分かりやすくするため環境変数の値を表示してます
api.all( '/*', function( req, res, next ){
if( settings_cors ){
res.setHeader( 'Access-Control-Allow-Origin', settings_cors );
res.setHeader( 'Vary', 'Origin' );
}
next();
});
res.setHeader( 'Access-Control-Allow-Origin', * );
としてあるからCORSの設定はできているはずでは!?!?(できていない)
試しにコメントアウトしてみると、ReactのGETが動かなくなるので、CORSの設定は効いているようだなぁ〜…。
axiosの書き方がおかしいのかなぁ〜とかReact側で色々やってたら時間が溶けてしまった(^^;;
結局
APIサーバー側expressにres.setHeader
の中身が足りなかった…
以下の表記を追加することで正しく動作した。
Access-Control-Allow-Headers
については不要かもしれない。
res.setHeader( 'Access-Control-Allow-Methods', '*' );
res.setHeader( 'Access-Control-Allow-Headers', '*' );
ついでに
内容とは関係ないが、CORSはブラウザ側の配慮であり、terminalなどからcurlでPOSTなどを直打ちする分には関係ない要素らしい。