localhost に立てた SPA と API に Android Emulator から localhost のまま接続する
モバイル向けSPAを開発中に、Android エミュレータで動作確認したいときの話です。
SPA 開発では、AWS Lambda や Azure Functions、Firebase Functions などに API を立て、フロントエンドは S3 や Firebase Hosting、Netlify などのホスティングサービスに配置することが多いでしょう。
これらを開発する時は、ローカルに
- localhost:3100 は API サーバー
- localhost:3200 は Web サーバー
のように開発用のサーバーを立てて(あるいはツールキットにより立てられて)使用すると思います。この時フロントエンドから API サーバーへのアクセスは、ttp://localhost:3100/api/ping
などとハードコードされていることがあります。
モバイルでの動作確認をするためには、Chrome などの開発者ツールで見た目だけを変えることもできますが、より実機に近い環境として、Android エミュレータを使うこともあるでしょう。
Android エミュレータは、自PCとは別の(独立した)ネットワーク上にあるため、エミュレータ内での localhost
は、当然ながらエミュレータ自身を示すため、開発PC で動作している SPA をエミュレータ内ブラウザで開くと、SPA から API サーバー(localhost:3100
)に到達できずエラーになります。
エミュレータから、その開発PC(ホストPC)へのアクセスは 10.0.2.2
で行えるので、ttp://localhost:3100/api/ping
を ttp://10.0.2.2:3100/api/ping
と書き換えれば動作するのですが、いちいち書き換えるのも面倒です。
エミュレータ内の特定ポートへの通信をホストPCへ転送する機能があればいいのに…って思ってましたが、実はありました!
こちらに習い、ホストPCで次のコマンドを実行します。
adb reverse tcp:3100 tcp:3100
これで、エミュレータ内の ttp://localhost:3100/api/ping
は、ホストPCへ転送され、SPA は正常に動作します。
SPA へのアクセスも、
adb reverse tcp:3200 tcp:3200
としておけば、エミュレータ内でも ttp://localhost:3200/indesx.html
が使用できるようになります。
Android アプリの WebView からアクセスする場合
現在の Android 開発では https 以外の通信は既定では使用不可となっているので、http://localhost
も開けません。
に習い、AndroidManifest.xml
に設定が必要です。
手軽な android:usesCleartextTraffic="true"
を使う場合は、Build Variant などを使い製品版のビルドでは false
となるようにしましょう。
Discussion