😗

localhost に立てた SPA と API に Android Emulator から localhost のまま接続する

2021/02/05に公開

モバイル向け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/pingttp://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