💨

Next.js + FastAPIでCORSエラーを解消する

2022/12/08に公開

サーバー構成

以下のようにローカルサーバーを立てて開発をしていました。
FastAPI: http://localhost:8080
Next.js: http://localhost:3000

すると、NextからPOSTリクエストをFastAPIに送信しようとしたら以下のエラーになりました。

Access to XMLHttpRequest at 'http://localhost:8080/customer' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

よくあるCORSエラーでした。

その1:POST送信のつもりがOPTIONSでの送信になっていた

下記記事を参考に、リクエストヘッダーを追加しました。

axios.post(API_URL + "/api",
      requestData,
      { headers: { "Content-type": "text/plain" } }
)

すると、リクエストメソッドはPOSTになりましたが、CORSエラーは解消しませんでした。

https://syachiku.net/react-axios-cors-post/

その2:そもそもCORSエラーをNext(フロント)側で解消するべきではない

CORSエラーはすごく簡単にいうと、APIサーバーへのアクセスが許可されていないことが原因です。
なので、CORSエラーを解消するとき、API側でフロントからのアクセスを許可する方が、より確実かつ実践的な解決策となります。

そこでFastAPIのCORS設定方法(https://fastapi.tiangolo.com/ja/tutorial/cors/)
を見てみると、以下のように設定すれば良いことがわかりました。

main.py
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()
# アクセスを許可するオリジン(URLのようなもの)を設定
origins = [
    "http://localhost:3000",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    # 認証情報のアクセスを許可(今回は必要ない)
    allow_credentials=True,
    # 全てのリクエストメソッドを許可(["GET", "POST"]など個別指定も可能)
    allow_methods=["*"],
    # アクセス可能なレスポンスヘッダーを設定(今回は必要ない)
    allow_headers=["*"],
)

この設定により、`http://localhost:3000からのアクセスは許可されたので、Next側からリクエストを送れるようになりました。

結論:CORSエラーはAPI側でなおす

どうしてもAPIがいじれない時を除いて、基本的にはAPI側で設定する方が良いと思います。
FastAPIに限らず、他のフレームワークでも設定は可能なので調べてみて下さい。
また、フレームワークにCORS設定がなくても、「nginx CORS」などで調べるとアプリケーションサーバ内でも設定できると思うので、調べてみて下さい。

Discussion