最近web開発の勉強がてらオリジナルのアプリを作成しています。
その中でめちゃくちゃハマった表題のエラーについて、メモを残します。
多分レアケースだと思うので、同じような状況になる方は少ないと思いますが・・・・
以下表現がややこしいかもしれませんが、ホストPCというのは手元で操作しているPCのことです。このPCの中でvirtualBoxを使ってubuntuの仮想環境(ゲストPC)を構築しています。
フロントエンドだけvirtualBoxの仮想環境を使い、バックエンドはvirtualBoxを使わずに、Pythonのvenvで環境構築をしています。
概要
フロントエンド(virtualBox: ubuntu、TypeScript React)、バックエンド(ホストPC、Python Django RestFramework)に分けて開発。
フロントエンドのサーバーはホストPCの3000番ポートをゲストPC(virtualBox)の3000番ポートにポートフォワード。ゲストPC上でreact-app startでサーバーを立てた後、ホストPCのブラウザからlocalhost:3000にアクセスしてページを表示。
バックエンドのAPIサーバーはホストPCでdjangoのmanage.py runserverをつかって起動。localhost:8000にアクセスするとAPIが得られる。
JavaScriptでバックエンドのAPIを取得する際に、表題のエラーが発生して、APIを取得できなかった。
最初やっていたこと
localhost:3000で表示しているwebページからlocalhost:8000のAPIサーバーを叩くので、プロキシが必要になります。(CORSエラーが発生するので)
プロキシにはhttp-proxy-middlewareを使用し、setUpProxy.jsには以下のように記述していました。
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
proxy("/api", {
target: localhost:8000,
changeOrigin: true,
});
)
}
/api にアクセスする際にlocalhost:3000からlocalhost:8000にプロキシするという意図で記載しています。
しかし、Chromeでconsoleを確認すると、504 Gateway Timeout となっており、APIサーバーからデータを取得できませんでした。
ただ、ブラウザから直接localhost:8000にアクセスすると、djangoのAPIページが表示されるという状態です。
原因
上記設定だとホストPCのlocalhost:8000ではなく、ゲストPC(virtualbox)のlocalhost:8000にアクセスしてしまっており、504エラーとなってしまう。
対策 結論
プロキシの設定を以下のように変更することで、ホストPCのlocalhost:8000にプロキシできます。
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
proxy("/api", {
target: http://10.0.2.2,
changeOrigin: true,
});
)
}
10.0.2.2はゲストPCからみたホストPCのIPアドレスです。この値は初期設定値ですので、変更している方は変更後のIPアドレスをしようしてください。
また、同時にDjangoのsettings.pyのALLOWED_HOSTSに上記のIPアドレスを追記します。(DEBUGモードの時のみ必要です。)
ALLOWED_HOSTS = ['10.0.2.2']
感想
めちゃくちゃハマってかなり苦しんだんですが、冷静に考えてみると当然の結果のようにも思えます。
インフラ周りは結構面白く感じていて、色々勉強していたのでどうにか気づくことができたのが救いです。
コメント