1. ホーム
  2. node.js

[解決済み] OPTIONSルートにCORSヘッダを追加しても、ブラウザが私のAPIにアクセスできないのはなぜですか?

2022-03-14 10:34:24

質問

Web フレームワーク Express.js を使用する Node.js アプリケーションで CORS をサポートしようとしています。私は、以下を読みました。 Googleグループでのディスカッション を処理する方法について、また、CORS がどのように機能するかについて、いくつかの記事を読みました。まず、こんなことをやってみました(コードはCoffeeScriptの構文で書かれています)。

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

うまくいかないようです。私のブラウザ(Chrome)は、最初のOPTIONSリクエストを送信していないようです。クロスオリジンのGETリクエストを送信する必要があるリソースのブロックを更新したところ。

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

動作します(Chromeの場合)。Safariでも動作します。

と読んだことがあるのですが・・・。

CORSを実装しているブラウザでは、クロスオリジンの各GETまたはPOSTリクエストの前に、GETまたはPOSTがOKであるかどうかをチェックするOPTIONSリクエストがあります。

そこで一番の疑問は、なぜ私のケースではこれが起きないように見えるのか、ということです。なぜ私のapp.optionsブロックは呼び出されないのでしょうか?なぜメインのapp.getブロックでヘッダーを設定する必要があるのでしょうか?

どうすればいいですか?

主な質問に答えると、CORS 仕様では、POST または GET に単純でないコンテンツまたはヘッダーがある場合にのみ、OPTIONS 呼び出しが POST または GET の前に来るよう要求しています。

CORS のプリフライトリクエスト(OPTIONS コール)を必要とする Content-Type は、すべての Content-Type ただし、以下を除く :

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

上記以外のContent-Typeを指定した場合、プリフライトのリクエストが発生します。

ヘッダーについては、すべてのリクエストヘッダー 下記以外の がプリフライトリクエストのトリガーとなります。

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  5. DPR
  6. Save-Data
  7. Viewport-Width
  8. Width

その他のリクエストヘッダはプリフライトリクエストのトリガーとなります。

そこで、次のようなカスタムヘッダを追加することができます。 x-Trigger: CORS そして、それがプリフライトリクエストのトリガーとなり、OPTIONSブロックをヒットさせるはずです。

参照 MDN Web API リファレンス - CORS Preflighted リクエスト