web-dev-qa-db-fra.com

Réaction de la requête réseau fetch () native

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);
      });
94
Alek Hurst

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>
124
Alek Hurst

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>
53
Lavi Avigdor

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

10
Mahmoodvcs

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>

React Native Docs -> Intégration avec des applications existantes -> Testez votre intégration -> Ajouter une exception de sécurité de transport d'application

8
Ocean Liu

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;

7
Dmitry Maksakov

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
 })
5
NickJ

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>
3
Johannes Spohr

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.

2
Varun Kumar

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" /> 
2
Shashwat

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.

1
Craciun Ciprian

Pour l'utilisateur Android: 

  1. Remplacez localhosts 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

  2. Si votre URL de requête est HTTPS et que votre appareil Android est sous un proxy, supposez que vous avez installé une autorité de certification ajoutée par l'utilisateur (comme l'autorité de certification de burp suite ou de Charles) dans votre appareil Android, assurez-vous que votre version Android est inférieure à Nougat (7.0), car: Modifications des autorités de certification de confiance dans Android Nougat

    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.

0
fangxing

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;
});
0
user3374790

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/';
0
Cho Cho

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);
     });
0
Lavaraju

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.

0
henryoats