反应本地 Android 抓取失败,连接到本地 API

我在我的本地 Android 应用程序中使用提取 API 来向本地 API 发出请求。我通常在 http://localhost:8163查询反应网络应用程序的 API。

我正在物理设备上以调试器模式测试我的应用程序。我在某个地方读到反应本地不能像 Web 应用程序那样查询本地主机。显然,你必须使用 http://10.0.2.2:[PORT_NUMBER_HERE]/,这是一个别名的“ http://127.0.0.1: [ PORT _ NUMBER _ here ]根据安卓模拟器停靠。我不确定这是不是我在物理设备上测试应该做的。

我的提取代码如下:

fetchToken() {
fetch('http://10.0.2.2:8163/extension/auth', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-type': 'application/json'
}
})
.then((response)) => console.log('successful fetchToken response: ', response.json()))
.catch((error) => console.log('fetchToken error: ', error))
.done();
}

请求总是挂起一段时间,然后到达带有无用错误 TypeError: Network request failed(...)catch块。检查本地 API 的日志,他们根本不注册请求。

因此,我不知道是否正确地查询了本地 API 以获取所需的资源,如果正确,我也不知道为什么获取失败。

116369 次浏览

You are not able to access your local development server because that port hasn't been forwarded by ADB yet. When you run react-native run-android, React Native maps the port 8081 with your mobile device on USB. When you disconnect your USB you won't be able to refresh or hot reload your code anymore. So in this situation you can do 2 things, either map your local server port just like React Native does or use your local IP address.

  1. Mapping Port

    This only works if you are using Android 6.0+. To forward a port using ADB run the following command in your terminal:

    adb reverse tcp:8163 tcp:8163
    

    This will map your local 8163 port to mobile's 8163 port. You'll be able to access your development server this way.

  2. Using local IP address

    You can also use your local IP on React Native development app to reload them without USB. Shake your device or long press the menu button to open developer menu. Open Dev Settings, then tap Debug server host & port for device. Here you can enter your machine's local IP with port number 8081. For ex. if your machine's IP is 192.168.1.100 then you'd enter 192.168.1.100:8081 in here for successful connection. Now we have covered that we can reload the app. After this when you want to use your local machine's development server use the same IP with your server's port number.

You should be good to go with this.

Had the same/similar issue - took me two full days to solve it. I use a Win10 machine with Visual Studio Code, attached Android device and a local PHP server for API. Maybe this will help somebody:

  1. Cable -> Try different USB-cables, out of my 3 cables only one works
  2. Connection mode -> Very important, I had to choose PTP mode to make it work
  3. Same network -> Phone and PC must be on the same network
  4. Private network -> The network must be a private network, public does not work
  5. IP -> Run ipconfig in PowerShell and get your IP4 address
  6. Firewall -> Accept the firewall-prompt
  7. PHP server -> Start built in PHP server with "php -S {your IP}:8081"
  8. Test PHP server -> Create index.php and open {your IP}:8081 on your phone
  9. Fetch -> Create fetch script (example below)

       fetch('http://{your IP}:8081/')
.then((response) => response.json())
.then((responseJson) => {
this.setState({ message : responseJson.message.data })
})
.catch((error) => {
console.error(error);
}); 

If you are using Metro Bundler in Expo Developer Tools Use CONNECTION LAN ip address Sample image Metro Bundler

How to used in react native

    getfetch = () => {
return fetch('http://LAN-IP-ADDRESS-HERE:4300/customers/',{
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
}
})
.then((response) => response.json())
.then((responseJson) => {


console.log(responseJson);


})
.catch((error) =>{
console.error(error);
});
}

Sample image REST API using postman

Sample image POSTMAN

Hopefully this is helpful :)

Maybe I'm late with the suggestion, but this helped me.

You should try http://0.0.0.0:8163/extension/auth

Run the below command to access localhost or 127.0.0.1 or your computer's ip

adb -s <device_name> reverse tcp:backend_port tcp:backend_port

Example:

adb -s emulator-5554 reverse tcp:3000 tcp:3000

Now, You can use like below in your component.

import React from 'react';
import {View,Image,TextInput, TouchableOpacity, StyleSheet, ImageBackground, AsyncStorage} from 'react-native';
import {Text,Button} from 'native-base';
export class Login extends React.Component{
constructor(props){
super(props);
this.state={username:'',password:''}
}
login = () =>{
fetch('http://localhost:3000/users',{
method:'POST',
headers:{
'Accept':'application/json',
'Content-Type':'application/json'
},
body:JSON.stringify({
username:this.state.username,
password:this.state.password
})
})
.then((response)=>response.json())
.then((res)=>{
if(res.success===true){
var username=res.message;
AsyncStorage.setItem('username',username);
this.props.navigation.navigate('app');
alert("Login success");
} else{
alert("Invalid Credentials");
}
})
.done();
}
render(){
return (
<View style={styles.content}>
<Text style={styles.logo}>- WELCOME -</Text>
<View>
<TextInput underlineColorAndroid='transparent' style={styles.input} placeholder="Username"
onChangeText={(username)=>this.setState({username})}
value={this.state.username}>
</TextInput>
<TextInput secureTextEntry={true} underlineColorAndroid='transparent' style={styles.input} placeholder="Password"
onChangeText={(password)=>this.setState({password})}
value={this.state.password}>
</TextInput>
</View>
<TouchableOpacity onPress={this.login} style={styles.buttonContainer}>
<Text style={styles.buttonText}>LOGIN</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex:1,
},
content:{
opacity:0.9,
backgroundColor:'white',
borderWidth:2,
margin:10,
alignItems: 'center',
},
logo:{
justifyContent: 'center',
alignItems: 'center',
fontSize:45,
color:'black',
textShadowColor:'gray',
textShadowRadius:10
},
input:{
borderRadius:10,
padding:10,
color:'black',
borderWidth:2,
borderColor:'lightgray',
width:200,
margin:5
},
buttonContainer:{
margin:10,
padding:10,
justifyContent: 'center',
alignItems: 'center',
},
buttonText:{
borderRadius:100,
padding:10,
backgroundColor:'magenta',
color:'white',
textAlign:'center',
width:100
}


});

Output:

enter image description here enter image description here

If you're using expo just copy the URL above QR code and add it to you API instead localhost

it will like this

{
expo host :http://192.168.0.109:{Your Port}/The name for your API
}

Open the console in you're desktop, type : ipconfig

you'll get an IPv4_Address

and try this : 'http://IPv4_Address:8163/extension/auth'

http or https based on it copy the URL

step 1: download ngrok unzip the package

step 2 :open ngrok.exe install it (or) double click on it terminal will be open

step 3:

ngrok http (port no of backend services)
        

eg:ngrok http 8081

step 4: copy url of https if it is https and then paste it in place of URL from UI.

Good day, This is working

I use my machine's IP the Ethernet adapter Ethernet 2: IPV4 Address

And allow my port on firewall both Inbound and outbound rules

enter image description here

In my case, I tried to make requests to http://localhost:3000 using axios but everytime I got Network Error as a response. Then I found out that I need to make request to http://10.0.2.2:3000 in case of android simulator. For iOS simulator it works fine with http://localhost:3000.

Conclusion

use

http://10.0.2.2:3000

instead of

http://localhost:3000

Update

Better option is to map your computer's local server port to same port in device

  1. See list of devices connected. It can be emulator or real device
$ adb devices


List of devices attached
emulator-5554   device <--- emulator
2681523e        device <-- real device
  1. map the ports
$ adb -s emulator-5554 reverse tcp:3000 tcp:3000


$ adb -s 2681572e reverse tcp:3000 tcp:3000

You are done.

Try to use 127.0.0.1 host. It worked for me.

I had the same issue and this solution worked for me:-

  • Step 1 : Get your IpV4 address by typing ipconfig in your terminal

  • Step 2 : Host your API at your IpV4 address instead of localhost (for eg :- 192.168.0.106:3000)

  • Step 3 : Run your API first

  • Step 4 : Fetch the data from the new address (for eg :- 192.168.0.106:3000)

  • Step 5 : Only then start your app with react-native start or npm start

In Android, we can use the IP 10.0.2.2 to access computers localhost.

const baseUrl = Platform.OS === 'android' ? 'http://10.0.2.2' : 'http://localhost';

This works like heaven

  http://10.0.2.2:8080

instead of

   http://localhost:8080

if localhost port is 8080

 adb reverse tcp:8080 tcp:8080

if your port is something else then replace with 8080