React Native fetch() Network Request Failed
JavascriptReact NativeFetch ApiJavascript Problem Overview
When I create a brand new project using react-native init
(RN version 0.29.1) and put a fetch in the render method to the public facebook demo movie API, it throws a Network Request Failed
. There is a very useless stack trace and I can't debug network requests in the chrome console. Here is the fetch I'm sending:
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
Javascript Solutions
Solution 1 - Javascript
The problem here is that iOS does not allow HTTP requests by default, only HTTPS. If you want to enable HTTP requests add this to your info.plist
:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Solution 2 - Javascript
Not recommended to allow all domains for http. Make an exception for just the necessary domains.
Source: Configuring App Transport Security Exceptions in iOS 9 and OSX 10.11
Add the following to the info.plist file of your app:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
Solution 3 - Javascript
I was using localhost
for the address, which was obviously wrong. After replacing it with the IP address of the server (in the network that emulator is), it worked perfectly.
Edit
In Android Emulator, the address of the development machine is 10.0.2.2
. More explanation here
For Genymotion, the address is 10.0.3.2
. More info here
Solution 4 - Javascript
I got the same issue on Android 9 because of the "http" and issue resolved by just adding android:usesCleartextTraffic="true" in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:usesCleartextTraffic="true"
.......>
.......
</application>
Solution 5 - Javascript
For us it was because we were uploading a file and the RN filePicker did not give the proper mime type. It just gave us 'image' as the type. We needed to change it to 'image/jpg' to get the fetch to work.
form.append(uploadFileName, {
uri : localImage.full,
type: 'image/jpeg',
name: uploadFileName
})
Solution 6 - Javascript
I got the same issue on Android but I managed to find a solution for it. Android is blocking cleartext traffic (non-https-requests) since API Level 28 by default. However, react-native adds a network-security-config to the debug version (android/app/src/debug/res/xml/react_native_config.xml
) which defines some domains (localhost, and the host IPs for AVD / Genymotion), which can be used without SSL in dev mode.
You can add your domain there to allow http requests.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">10.0.2.2</domain>
<domain includeSubdomains="false">10.0.3.2</domain>
<domain includeSubdomains="true">dev.local</domain>
</domain-config>
</network-security-config>
Solution 7 - Javascript
React Native Docs gives the answer for this.
> Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project's Info.plist (or equivalent) file.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
Solution 8 - Javascript
For Android user:
Replace localhost
s to a Lan IP addresses because when you run the project on an Android device, localhost is pointing to the Android device, instead of your computer, example: change http://localost
to http://192.168.1.123
2. If your request URL is HTTPS and your Android device is under a proxy, assume you have installed User-added CA(like burp suite's CA or Charles's CA) in your Android device, make sure your Android version is below Nougat(7.0), because: Changes to Trusted Certificate Authorities in Android Nougat
> User-added CAs
> Protection of all application data is a key goal of the
> Android application sandbox. Android Nougat changes how applications
> interact with user- and admin-supplied CAs. By default, apps that
> target API level 24 will—by design—not honor such CAs unless the app
> explicitly opts in. This safe-by-default setting reduces application
> attack surface and encourages consistent handling of network and
> file-based application data.
Solution 9 - Javascript
The problem may be in server configuration.
Android 7.0 has a bug described here. Workaround proposed by Vicky Chijwani:
> Configure your server to use the elliptic curve prime256v1. For > example, in Nginx 1.10 you do this by setting ssl_ecdh_curve > prime256v1;
Solution 10 - Javascript
I was having this problem for Android-
URL- localhost/authToken.json - didn't work :(
URL- 10.106.105.103/authToken.json - didn't work :(
URL- http://10.106.105.103/authToken.json - worked :) :D
Note- Use ifconfig
on Linux or ipconfig
on Windows to find machine IpAddress
Solution 11 - Javascript
if you using localhost just change it :
from :http://localhost:3030
to :http://10.0.2.2:3030
Solution 12 - Javascript
I came across the same issue on Android Emulator, where I tried to access an external HTTPS URL with a valid certificate. But fetching that URL in react-native failed
'fetch error:', { [TypeError: Network request failed]
sourceURL: 'http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false' }
-
To find out the exact error in the logs, I first enabled 'Debug JS Remotely' using Cmd + M on the app
-
The error reported was
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
- I added the URL's valid certificate using this method -> STEP 2
http://lpains.net/articles/2018/install-root-ca-in-android/
This certificate gets added to the User tab.
- Add the attribute
android:networkSecurityConfig
attribute to AndroidManifest.xml
Add a Network Security Configuration file
res/xml/network_security_config.xml:
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="user"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
This should work and give you an expected response.
Solution 13 - Javascript
For Android, you may have missed to add permission in AndroidManifest.xml Need to add the following permission.
<uses-permission android:name="android.permission.INTERNET" />
Solution 14 - Javascript
I have similar problem. In my case requests to localhost was working and suddenly stopped. It turn out that the problem was that I was turn off my wifi on my android phone.
Solution 15 - Javascript
This worked for me, android uses a special type of IP address 10.0.2.2 then port number
import { Platform } from 'react-native';
export const baseUrl = Platform.OS === 'android' ?
'http://10.0.2.2:3000/'
:
'http://localhost:3000/';
Solution 16 - Javascript
if you use docker for the REST api, a working case for me was to replace hostname: http://demo.test/api
with the machine ip address: http://x.x.x.x/api
. You can get the IP from checking what ipv4 you have on your wireless network. You should have also the wifi from phone on.
Solution 17 - Javascript
You should handle the error case in .then for fetch API.
For example:
fetch(authURl,{ method: 'GET'})
.then((response) => {
const statusCode = response.status;
console.warn('status Code',statusCode);
if(statusCode==200){
//success code
}else{
//handle other error code
}
},(err) => {
console.warn('error',err)
})
.catch((error) => {
console.error(error);
return error;
});
Solution 18 - Javascript
By running the mock-server on 0.0.0.0
Note: This works on Expo when you are running another server using json-server.
Another approach is to run the mock server on 0.0.0.0 instead of localhost or 127.0.0.1.
This makes the mock server accessible on the LAN and because Expo requires the development machine and the mobile running the Expo app to be on the same network the mock server becomes accessible too.
This can be achieved with the following command when using json-server
json-server --host 0.0.0.0 --port 8000 ./db.json --watch
Visit this link for more information.
Solution 19 - Javascript
in my case i have https url but fetch return Network Request Failed error so i just stringify the body and it s working fun
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue'
})
});
Solution 20 - Javascript
For me ... I have https
already ... and the issue went away once I added 'Content-type': 'application/json'
to headers
headers: {
Authorization: token,
'Content-type': 'application/json',
/** rest of headers... */
}
Platform: Android
Solution 21 - Javascript
HTTP
is not allowed anymore. Pleas use HTTPS
Starting with Android API 28 and iOS 9, these platforms disable insecure HTTP connections by default.
Solution 22 - Javascript
Just add
<uses-permission android:name="android.permission.INTERNET" />
<application
android:usesCleartextTraffic="true"
in your AndroidManifest.xml and then replace fetch URL domain (localhost) with your IP address,
const dataRaw = await fetch('http://192.168.8.102:4000');
Solution 23 - Javascript
It my case, it was showing same for https
requests as well.
Reinstalling the application solved it.
Solution 24 - Javascript
-
Add
android:usesCleartextTraffic="true"
line in AndroidManifest.xml. -
Delete all debug folder from your android folder.
Solution 25 - Javascript
This is not an answer but option. I switched to https://github.com/joltup/rn-fetch-blob It works good both for form-data and files
Solution 26 - Javascript
The solution is simple update nodejs version 14 or higher
Solution 27 - Javascript
"dependencies": {"react": "17.0.2","react-native": "0.66.1"},
I faced this problem with the Android emulator.
-
Add these lines of code inside AndroidManifest.xml
<application .... .... android:usesCleartextTraffic="true">
-
Then, try to run your code in a real physical device, instead of emulator,
to run on physical devices - connect your usb and try to run npx react-native run-android
Solution 28 - Javascript
Just you have Changes in Fetch....
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
/*return responseJson.movies; */
alert("result:"+JSON.stringify(responseJson))
this.setState({
dataSource:this.state.dataSource.cloneWithRows(responseJson)
})
}).catch((error) => {
console.error(error);
});
Solution 29 - Javascript
For Android devices, go to your project root folder and run the command:
adb reverse tcp:[your_own_server_port] tcp:[your_own_server_port]
e.g., adb reverse tcp:8088 tcp:8088
This will make your physical device(i.e. Android phone) listen to the localhost server running on your development machine (i.e. your computer) on address http://localhost:[your_own_server_port].
After that, you can directly use http:localhost:[your_port] /your_api
in your react-native fetch(
) call.
Solution 30 - Javascript
For android, add android:networkSecurityConfig="@xml/network_security_config" to application tag in AndroidManifest.xml, like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
</manifest>
network_security_config.xml file content:
<?xml version='1.0' encoding='utf-8'?>
<network-security-config>
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
</trust-anchors>
</debug-overrides>
<!-- let application to use http request -->
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
Solution 31 - Javascript
In my case, the Android emulator wasn't connected to the Wi-Fi.