Lorsque je crée un nouveau projet à l'aide de react-native init
(version RN 0.29.1) et que je mets une récupération dans la méthode de rendu à l'API publique de démonstration sur facebook, un Network Request Failed
est généré. Il y a une trace de pile très inutile et je ne peux pas déboguer les demandes réseau dans la console Chrome. Voici le fetch que j'envoie:
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
Le problème ici est que iOS n'autorise pas les demandes HTTP par défaut, uniquement le protocole HTTPS. Si vous souhaitez activer les requêtes HTTP, ajoutez ceci à votre info.plist
:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Il n'est pas recommandé d'autoriser tous les domaines pour http . Faites une exception pour les domaines nécessaires uniquement.
Source: Configuration des exceptions de sécurité du transport d'application dans iOS 9 et OSX 10.11
Ajoutez les éléments suivants au fichier info.plist de votre application:
<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>
J'utilisais localhost
pour l'adresse, ce qui était manifestement faux. Après le remplacer par l'adresse IP du serveur (dans le réseau de l'émulateur), cela fonctionnait parfaitement.
Modifier
Dans Android Emulator, l'adresse de la machine de développement est 10.0.2.2
. Plus d'explication ici
Pour Genymotion, l’adresse est 10.0.3.2
. Plus d'infos ici
React Native Docs donne la réponse à cela.
Apple a bloqué le chargement implicite des ressources HTTP en texte clair. Nous devons donc ajouter ce qui suit le fichier Info.plist (ou équivalent) suivant notre projet.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
Le problème peut être dans la configuration du serveur.
Android 7.0 a un bug décrit ici . Solution proposée par Vicky Chijwani:
Configurez votre serveur pour utiliser la courbe elliptique prime256v1. Pour Par exemple, dans Nginx 1.10, vous le faites en définissant ssl_ecdh_curve prime256v1;
Pour nous, c’était parce que nous téléchargions un fichier et que le RN filePicker ne donnait pas le type de mime approprié. Cela nous a juste donné "image" comme type. Nous devions le changer en 'image/jpg' pour que le traitement au travail puisse fonctionner.
form.append(uploadFileName, {
uri : localImage.full,
type: 'image/jpeg',
name: uploadFileName
})
J'ai le même problème sur Android, mais j'ai réussi à trouver une solution. Android bloque le trafic en clair (demandes non https) depuis le niveau 28 de l'API par défaut. Cependant, react-native ajoute une configuration de sécurité réseau à la version de débogage (Android/app/src/debug/res/xml/react_native_config.xml
) qui définit certains domaines (localhost et les adresses IP d’hôte pour AVD/Genymotion), qui peuvent être utilisés sans SSL en mode dev. Vous pouvez y ajouter votre domaine pour autoriser les requêtes http.
<?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>
J'avais ce problème pour Android-
URL- localhost/authToken.json - n'a pas fonctionné :(
URL- 10.106.105.103/authToken.json - n'a pas fonctionné :(
URL- http://10.106.105.103/authToken.json - travaillé :): D
Remarque: Utilisez ifconfig
sous Linux ou ipconfig
sous Windows pour rechercher l'ordinateur IpAddress.
J'ai le même problème. Dans mon cas, les demandes adressées à localhost fonctionnaient et se sont soudainement arrêtées….
Pour Android, vous avez peut-être oublié d'ajouter une autorisation dans AndroidManifest.xml Besoin d'ajouter l'autorisation suivante.
<uses-permission Android:name="Android.permission.INTERNET" />
si vous utilisez docker pour l'API REST, mon cas était de remplacer le nom d'hôte: http://demo.test/api
par l'adresse IP de la machine: http://x.x.x.x/api
. Vous pouvez obtenir l'adresse IP en vérifiant quel ipv4 vous avez sur votre réseau sans fil. Vous devriez aussi avoir le wifi du téléphone.
Pour l'utilisateur Android:
Remplacez localhost
s par une adresse IP LAN, car lorsque vous exécutez le projet sur un périphérique Android, localhost pointe sur le périphérique Android et non sur votre ordinateur, par exemple, remplacez http://localost
par http://192.168.1.123
.
CA ajoutées par l'utilisateur
La protection de toutes les données de l’application est l’un des objectifs clés du Sandbox d'application Android. Android Nougat change la manière dont les applications interagissez avec les autorités de certification fournies par l'utilisateur et par l'administrateur. Par défaut, les applications qui L'API cible de niveau 24 n'honorera pas, de par leur conception, ces autorités de certification, sauf si l'application accepte explicitement. Ce paramètre sécurisé par défaut réduit l'application attaque surface et encourage une manipulation cohérente du réseau et données d'application basées sur des fichiers.
Vous devez gérer le cas d'erreur dans .then for fetch API.
Par exemple:
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;
});
Cela a fonctionné pour moi, Android utilise un type spécial d'adresse IP 10.0.2.2, puis le numéro de port
import { Platform } from 'react-native';
export const baseUrl = Platform.OS === 'Android' ?
'http://10.0.2.2:3000/'
:
'http://localhost:3000/';
Juste vous avez des changements dans 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);
});
Je suis tombé sur le même problème sur Android Emulator, où j'ai essayé d'accéder à une URL HTTPS externe avec un certificat valide. Mais récupérer cette URL dans react-native a échoué
'fetch error:', { [TypeError: Network request failed]
sourceURL: 'http://10.0.2.2:8081/index.delta?platform=Android&dev=true&minify=false' }
1) Pour connaître l'erreur exacte dans les journaux, j'ai d'abord activé "Débogage JS à distance" à l'aide de Cmd + M sur l'application.
2) L'erreur signalée était
Java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
3) J'ai ajouté le certificat valide de l'URL en utilisant cette méthode -> STEP 2
http://lpains.net/articles/2018/install-root-ca-in-Android/
Ce certificat est ajouté à l'onglet Utilisateur.
4) Ajoutez l'attribut Android:networkSecurityConfig
à AndroidManifest.xml
Ajouter un fichier de configuration de la sécurité réseau 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>
Cela devrait fonctionner et vous donner une réponse attendue.