CORSとは何か(解決編)

CORSを使う

の前に、CORSには二つのリクエストがあるという話を入れる

CORSのリクエストは二つ

  1. 単純リクエス
  2. プリフライトリクエス

単純リクエストとは?

  • GET, HEAD, POST のリクエス
  • Content-Type ヘッダーに、 application/x-www-form-urlencodedmultipart/form-datatext/plain が入るリクエス

参考:https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#simple_requests

  • 普通のリクエストだと思えば良さそう
  • 普通というのが、難しいですが、リクエストがあったらすぐに、サーバー側にリクエストが飛ぶという感覚(後述のプリフライトリクエストを読むとわかるかと・・)

プリフライトリクエス

  • リクエストがあったら(実際のリクエスト と呼ぶことにする)、サーバー側に実際のリクエストがすぐに飛ぶのではなく、その前に OPTIONS というHTTPリクエストが飛ぶ
  • OPTIONSリクエストは、実際のリクエストをサーバー側に送信しても安心であるかを確かめるリクエストで、実際のリクエストが、ユーザーデータに影響を与える場合に、OPTIONS リクエストを送る
  • ユーザーデータに影響を与える場合は、例えば、 POST, PATCH, DELETEなどのリクエス

参考:https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#preflighted_requests

  • OPTIONSリクエストをPassするには、レスポンスヘッダーに POST, PATCH, DELETEなどのリクエストを含めなければいけない
  • レスポンスヘッダーなので、サーバー側での設定が必要となる

実際、どういうエラーが出るのか

  • 実際にfrontend ⇒ backendにPOSTリクエストを送ったときのエラーはこちら
Access to XMLHttpRequest at 'http://localhost:8000/api/v1/calc/calc_kakeibo_from_csv' 
from origin 'http://localhost:3000' 
has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • developerツールのNetworkでも確認できますね(すいません、拡大してください 🙏)

f:id:YukiMatsu88:20210622194221p:plain
corsエラー_1

  • Consoleにエラーメッセージが出てます(すいません、拡大してください🙏)

f:id:YukiMatsu88:20210622194303p:plain
corsエラー_2

注目すべきは・・・

No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • Access-Control-Allow-Origin ヘッダーがないと言われたので、設定する

FastAPIの設定

  • FastAPIでは、 CORSMiddleware を使用して、CORSの設定ができる
  • こんな感じで設定
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI(
    title="calc_csv_kakeibo_backend",
    version="1.0",
)

origins = [
    "http://localhost:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    # オリジン間リクエストでCookieをサポートするのでTrue
    allow_credentials=True,
       # 今作ってるアプリでは、POSTしかしないので一旦POSTのみ
    allow_methods=["POST"],
    # 全て許可
    allow_headers=["*"],
    # 全て許可
    expose_headers=["*"],
)

日本語で書いてあるので、ここを読めばどういうふうに設定すればわかりそう

https://fastapi.tiangolo.com/ja/tutorial/cors/#corsmiddleware

許可されたか確認してみる

f:id:YukiMatsu88:20210622194631p:plain

  • ちゃんと、Access-Control-Allow-Originlocalhost:3000 が設定されてそう

開発してても、既にこの辺は設定済みなので、アプリ自作しなかったら、こんなに調べなかったので、良い機会でした ☀️

参考:https://qiita.com/10mi8o/items/2221134f9001d8d107d6