Nest.jsで作ったAPIをReactからfetchしようとした時に
「CORSポリシーによってブロックされています」とエラーが表示されたので、その解決方法をメモします。
エラー内容
Access to fetch at 'http://localhost:3000/item' from origin 'http://localhost:4000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
書いてあること
- CORSポリシーによってブロックされています。
- リクエストされたリソースに 'Access-Control-Allow-Origin' ヘッダーがありません。
CORSは日本語で「オリジン間リソース共有」です。
プロトコル、ポート番号、ホストが等しい場合が、同一のオリジンと言います。
セキュリティ上の理由で、ブラウザはオリジン間の通信を制限しています。
「同一オリジンポリシー」に従って制限されています。
解決方法
サーバーサイドの実装
「Access-Control-Allow-Origin」を設定する必要があります。
(他のサイトでは⇩も設定が必要と書いて有りましたがエラーなく通信できました)
「Access-Control-Allow-Headers」 これについて後で調べてみます。
Nest.jsで実際に実装した例
main.ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// ======↓が該当箇所======
app.enableCors({
origin: 'http://localhost:4000',
// allowedHeaders: 'Origin, X-Requested-With, Content-Type, Accept', ←無しでもエラーなくなったが、他のサイトには必要と書いてあった↓
});
// ======↑が該当箇所======
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
「http://localhost:4000 」からのアクセスができるようになります。
自分の環境(クライアントサイドの)に合わせて、設定してください。
「origin:*」とすると全て許可です。
クライアントサイドの実装
fetchでAPIを叩く場合は、「mode cors」の設定が必要です。
Reactで実際に実装した例
App.tsx
await fetch('http://localhost:3000/item', {
mode: 'cors'
})
.then(// 以下省略
これでエラーなく通信できるようになりました。