React Nativeを使ってAndroidアプリを開発していた際にaxiosを用いてローカルサーバーのAPIを呼び出そうとしたときにできなくて詰まったので解決策をメモします。
環境
- OS: Mac OS X 10.15.7 19H512
- react: 16.13.1
- react-native: 0.63.2
- axios: 0.21.0
- Android Emulator: 30.0.26-6755297
- Android: 11.0 (R) - API 30
事象
ローカルにAPIサーバーとしてRuby on Railsをポート3000番で動かしていました。
しかし、Android(React Native)側でaxiosを使ったPOSTリクエストを実行したところ、以下のエラーが搬送され意図した処理が行われませんでした。
Error: Network Error
at createError (createError.js:16)
at EventTarget.handleError (xhr.js:84)
at EventTarget.dispatchEvent (event-target-shim.js:818)
at EventTarget.setReadyState (XMLHttpRequest.js:600)
at EventTarget.__didCompleteResponse (XMLHttpRequest.js:395)
at XMLHttpRequest.js:508
at RCTDeviceEventEmitter.emit (EventEmitter.js:189)
at MessageQueue.__callFunction (MessageQueue.js:416)
at MessageQueue.js:109
at MessageQueue.__guard (MessageQueue.js:364)
その時のソースコードはこちらです。
import axios from 'axios';
URL = 'http://localhost:3000'
export const login = async (email, password) => {
return await axios
.post(URL + '/api/sign_in', {
email: email,
password: password,
})
.then((response) => {
return response;
})
.catch((error) => {
return { 'error' : error };
});
};
解決法
以下の通りです。
- URLのホストを
localhost
から10.0.2.2
に変更する
Android Studio ユーザーガイドには以下のように書かれていました。
開発マシンのアドレス 127.0.0.1 は、エミュレータ固有のループバック インターフェースと一致することになります。開発マシンのループバック インターフェース(マシン上の別名 127.0.0.1)で実行されているサービスにアクセスする場合は、代わりに特殊アドレス 10.0.2.2 を使用する必要があります。
引用: Android Studio ユーザーガイド - Android Emulator のネットワークを設定する
上の通り127.0.0.1
を使用するとAndroid Emulator自身をさすことになるのでローカルのサービスにアクセスするには特別なアドレスである10.0.2.2
を使う必要があるとのことです。
もちろん127.0.0.1
のエイリアスであるlocalhost
も同じように対応しないといけないということですね。。
以下の通り変更します。
// ここから
URL = 'http://localhost:3000'
// こう
URL = 'http://10.0.2.2:3000'
無事に解決しました。
参考
- Ararami Studio - Androidのエミュレーターから自身のPC(localhost)へ接続
- Android Studio ユーザーガイド - Android Emulator のネットワークを設定する