[Next.js] API リクエストの CORS エラーを回避する
こんにちは、よしお (@yoshio__25) です。
Webフロントエンジニアは皆さん、下のエラーを一度は目にしたことがあるのではないでしょうか。
Access to fetch at '' from origin '' has been blocked by CORS policy
CORSとは
MDN に以下のように記述されています。
オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。
つまり上のエラーメッセージは、異なるオリジンへのアクセスをしようとしたときに、セキュリティ上の理由からそのポリシーに反しているため、リクエストをブロックした旨を伝えています。
このポリシーはもちろん製品の開発時にも適用されます。
つまり開発用の localhost サーバーを立てて、そこから開発用の API サーバーにアクセスしたときも、上記エラーは発生するということです。
回避方法
API サーバーでの回避方法
このエラーの回避にはいくつか方法があります。
例えば API サーバーに Express を利用しているのであれば cors パッケージが利用できます。
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
ただしこれでは API サーバーへの改修も必要ですし、 Express 以外が利用されている場合には別の対策を考える必要があります。
Next.js での回避方法
Webフロントに Next.js を利用しているのであれば、それにぴったり合う機能が用意されています。
Rewrites は、あるリクエストを別のパスにマッピングする機能になります。
module.exports = {
async rewrites() {
return [
{
source: '/about',
destination: '/',
},
];
},
};
しかもこの機能はマッピング先を Next.js 内のルーティングだけでなく、外部の URL に対しても行うことができます。
module.exports = {
async rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
];
},
};
これを利用することで、例えば localhost での開発時にも、開発用の API サーバーへ直接リクエストを行うことが簡単にできます。
const rewrites = process.env.NODE_ENV === 'development' ? [
{
source: '/api/:path*',
destination: 'https://dev.api.example.com/:path*',
},
] : [];
module.exports = {
async rewrites() {
return rewrites;
},
};
fetch('http://localhost:3000/api/user')
// -> https://dev.api.example.com/user
まとめ
Webフロントエンドの開発時によく目にする CORS エラーですが、 Next.js を利用していれば Rewrites 機能を利用することで簡単に対処することができます。
Discussion