開発環境でのAPIリクエストのプロキシ
注: この機能は
react-scripts@0.2.3
以降で利用可能です。
多くの場合、フロントエンドのReactアプリは、バックエンドの実装と同じホストとポートで提供されます。
たとえば、アプリのデプロイ後の本番環境のセットアップは次のようになります。
/ - static server returns index.html with React app
/todos - static server returns index.html with React app
/api/todos - server handles any /api/* requests using the backend implementation
このようなセットアップは**必須ではありません**。ただし、このようなセットアップを使用している場合、開発中に別のホストまたはポートにリダイレクトすることを心配せずに、`fetch('/api/todos')`のようなリクエストを記述すると便利です。
開発サーバーに、開発環境で不明なリクエストをAPIサーバーにプロキシするように指示するには、`package.json`に`proxy`フィールドを追加します。次に例を示します。
"proxy": "http://localhost:4000",
このように、開発中に`fetch('/api/todos')`を実行すると、開発サーバーはそれが静的アセットではないことを認識し、リクエストをフォールバックとして`http://localhost:4000/api/todos`にプロキシします。開発サーバーは、`Accept`ヘッダーに`text/html`が含まれていないリクエストのみをプロキシに送信しようとします。
これは、開発環境でCORSの問題や次のようなエラーメッセージを回避するのに便利です。
Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
`proxy`は開発環境(`npm start`を使用)でのみ有効であり、本番環境で`/api/todos`のようなURLが正しい場所を指すようにするのはユーザーの責任であることに注意してください。 `/api`プレフィックスを使用する必要はありません。 `text/html` acceptヘッダーのない認識されないリクエストはすべて、指定された`proxy`にリダイレクトされます。
`proxy`オプションは、HTTP、HTTPS、およびWebSocket接続をサポートしています。
`proxy`オプションが十分に柔軟でない場合は、代わりに次のことができます。
- プロキシを自分で構成する
- サーバーでCORSを有効にする(Expressでの方法はこちら)。
- 環境変数を使用して、適切なサーバーホストとポートをアプリに挿入します。
プロキシ設定後の「無効なホストヘッダー」エラー
`proxy`オプションを有効にすると、より厳密なホストチェックがオプトインされます。これは、バックエンドをリモートホストに開放したままにすると、コンピューターがDNSリバインディング攻撃に対して脆弱になるため、必要です。この問題は、この記事とこの問題で説明されています。
`localhost`で開発している場合は、これは影響しませんが、ここで説明されているようにリモートで開発している場合は、`proxy`オプションを有効にした後、ブラウザに次のエラーが表示されます。
無効なホストヘッダー
これを回避するには、プロジェクトのルートにある`。env.development`というファイルにパブリック開発ホストを指定します。
HOST=mypublicdevhost.com
開発サーバーを再起動して、指定されたホストからアプリを読み込むと、動作するはずです。
それでも問題が発生する場合、またはクラウドエディターなどのより特殊な環境を使用している場合は、`.env.development.local`に1行追加することで、ホストチェックを完全にバイパスできます。 **これは危険であり、悪意のあるWebサイトからのリモートコード実行に対してマシンを公開することに注意してください。**
# NOTE: THIS IS DANGEROUS!
# It exposes your machine to attacks from the websites you visit.
DANGEROUSLY_DISABLE_HOST_CHECK=true
このアプローチはお勧めしません。
プロキシの手動設定
注: この機能は`react-scripts@2.0.0`以降で利用可能です。
`proxy`オプションが十分に柔軟でない場合は、Expressアプリインスタンスに直接アクセスして、独自のプロキシミドルウェアをフックできます。
この機能は`package.json`の`proxy`プロパティと組み合わせて使用できますが、すべてのロジックを`src/setupProxy.js`に統合することをお勧めします。
まず、npmまたはYarnを使用して`http-proxy-middleware`をインストールします。
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
次に、`src/setupProxy.js`を作成し、次の内容を配置します。
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
// ...
};
これで、プロキシを自由に登録できます!上記の`http-proxy-middleware`を使用した例を次に示します。
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
**注:** このファイルをどこにもインポートする必要はありません。開発サーバーを起動すると自動的に登録されます。
**注:** このファイルは、NodeのJavaScript構文のみをサポートしています。サポートされている言語機能のみを使用してください(つまり、Flow、ES Modulesなどはサポートされていません)。
**注:** プロキシ関数にパスを渡すと、パスでグロビングやパターンマッチングを使用できます。これは、expressルートマッチングよりも柔軟です。