E-NO
Applications mobiles 11 min de lecture

Dépannage réseau React Native : guide pratique pour émulateurs, simulateurs et appareils

calendar_today Publié : 2026-08-07
update Dernière mise à jour : 2026-08-07
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Dépannage réseau React Native : guide pratique pour émulateurs, simulateurs et appareils ».

Introduction

Les problèmes réseau React Native se déguisent souvent en bogues d'application alors que les vrais coupables sont le DNS, les ports, le routage, les pare-feu, les proxys ou le TLS. La voie la plus rapide vers une solution est une approche disciplinée et mesurable : commencez par un test de santé ciblé, vérifiez depuis le runtime d'appareil que vous utilisez réellement (émulateur Android, simulateur iOS ou appareil physique), puis élargissez seulement après avoir obtenu une référence verte.

Ce guide est orienté praticien. Vous allez inventorier versions et topologie, appliquer une configuration sûre et réversible, exécuter des diagnostics concrets avec résultats attendus, associer les échecs courants à leurs correctifs, et utiliser une liste de contrôle reproductible d'un projet à l'autre. Le même manuel fonctionne que vous construisiez avec React Native pur ou Expo, et que votre backend soit REST, GraphQL ou une autre API.

Inventaire des versions et de l'environnement

Avant de modifier des réglages, capturez l'environnement exact. Cela évite de poursuivre des différences entre machines et rend les problèmes reproductibles.

Enregistrer les versions de l'application et de l'outillage

node -v
npm -v
# ou si vous utilisez yarn ou pnpm
yarn -v
pnpm -v
npx react-native info
adb version
emulator -version
xcodebuild -version
xcrun simctl list devices

Capturer le contexte appareil/runtime

  • Utilisez-vous l'émulateur Android, le simulateur iOS, Expo Go ou un appareil physique ?
  • L'appareil est-il sur le même réseau local que votre machine de développement ?
  • Un VPN ou un proxy d'entreprise est-il activé ?

Capturer les points de terminaison et ports du backend

  • URLs exactes incluant schéma et port, par exemple :
  • https://api.exemple.local:8443/healthz
  • http://192.168.1.50:3000/ping
  • Domaines de recherche DNS ou DNS à horizon partagé dont vous dépendez.

Instantané de la configuration réseau sur votre machine de développement

macOS :

scutil --dns
networksetup -getwebproxy Wi-Fi
ifconfig

Linux :

resolvectl status || systemd-resolve --status
ip addr
ip route

Windows (PowerShell) :

Get-DnsClientServerAddress
Get-NetIPConfiguration
netsh winhttp show proxy

Choisissez un point de terminaison de santé simple et un runtime (par exemple, l'émulateur Android). Visez d'abord une requête HEAD ou GET 200 OK réussie. Étendez aux autres runtimes seulement après vérification. Un pilote étroit et mesurable est plus facile à inspecter localement et évite de combiner les variables.

Choisir une cible pilote minimale

Chemin de configuration sûr

Utilisez les bons noms d'hôtes et des réglages réversibles. Le tableau ci-dessous indique la bonne façon d'atteindre votre machine de développement depuis différents runtimes.

RuntimeHôte pour atteindre votre machine de devMapping de port optionnelNotes
Émulateur Android (AVD)http://10.0.2.2adb reverse tcp:3000 tcp:300010.0.2.2 pointe vers la boucle locale de l'hôte. Le mapping inverse permet à un appareil physique d'atteindre les ports de l'hôte.
Appareil Android (USB)http://127.0.0.1 avec adb reverse, ou http://<IP_LAN>adb reverse tcp:3000 tcp:3000Sans reverse, utilisez l'IP LAN de votre machine sur le même réseau.
Simulateur iOShttp://localhostNon requisLe simulateur partage la pile réseau de l'hôte.
Appareil iOS (Wi-Fi)http://<IP_LAN>Non disponibleAssurez-vous que l'appareil et la machine sont sur le même LAN.
Expo Go (Android)http://10.0.2.2 (émulateur) ou http://<IP_LAN> (appareil)adb reverse optionnelExpo Go utilise le réseau de l'appareil ; les mêmes règles s'appliquent.

Principaux motifs sûrs (développement seulement)

Mapping de port de développement Android avec adb reverse

adb reverse tcp:3000 tcp:3000
# supprimer les mappings quand terminé
adb reverse --remove-all

Si votre API de développement est en http (pas https), ajoutez une configuration de sécurité réseau en mode debug seulement et référencez-la depuis le manifeste debug. Exemple : android/app/src/debug/res/xml/network_security_config.xml

Autorisation cleartext en développement seulement (Android)

<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">192.168.1.50</domain>
  </domain-config>
</network-security-config>

Dans android/app/src/debug/AndroidManifest.xml :

<application
  android:networkSecurityConfig="@xml/network_security_config"
  ...>
</application>

Supprimez pour les builds de production.

Pour les points de terminaison http pendant le développement seulement, ajoutez à ios/<App>/Info.plist sous une configuration debug :

Relaxation ATS en développement seulement (iOS)

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Supprimez avant de livrer. Préférez HTTPS de bout en bout.

Préférez faire confiance à un certificat d'autorité locale au niveau OS. Sur Android 7+, si vous avez besoin que l'application fasse confiance aux AC installées par l'utilisateur pendant le développement, déclarez une configuration de sécurité réseau debug-only qui fait confiance aux certificats utilisateur. Sur iOS, installez le profil d'AC et marquez-le comme approuvé pour SSL.

TLS auto-signé en développement

CORS est un modèle de sécurité navigateur ; les piles réseau React Native ne l'appliquent pas de la même façon. Si votre serveur bloque les requêtes à cause d'Origin ou d'en-têtes personnalisés, c'est une politique côté serveur, pas une limitation du runtime client.

Ne pas supposer CORS dans React Native

Certains réseaux mobiles préfèrent IPv6. Utilisez des noms d'hôtes explicites et assurez-vous que votre DNS renvoie des enregistrements que votre service supporte. Si vous vous connectez par IP littérale, préférez les adresses IPv4 quand votre service est IPv4-only.

IPv4 vs IPv6

Vérification et diagnostics

Suivez ces étapes dans l'ordre. Arrêtez-vous quand vous obtenez un résultat vert ; puis élargissez la portée au runtime ou point de terminaison suivant.

1. Confirmer la connectivité au niveau application avec NetInfo

import NetInfo from "@react-native-community/netinfo\);n
NetInfo.fetch().then(state => {
  console.log("isConnected:" state.isConnected);
  console.log("isInternetReachable:" state.isInternetReachable);
});

Résultat attendu : isConnected true et isInternetReachable true sur un réseau fonctionnel. Si faux, résolvez la connectivité de l'appareil (Wi-Fi, cellulaire, portail captif) avant de continuer.

2. Tester une requête HEAD simple depuis l'application

Utilisez un minuscule point de terminaison comme /healthz qui ne fait aucun travail lourd.

// Exemple : fetch robuste avec timeout via AbortController
const withTimeout = (ms, controller) => setTimeout(() => controller.abort(), ms);

async function checkHealth(url) {
  const controller = new AbortController();
  const timer = withTimeout(5000, controller);
  try {
    const res = await fetch(url, { method: 'HEAD', signal: controller.signal });
    console.log('status', res.status);
    return res.ok;
  } catch (e) {
    console.log('error', String(e));
    return false;
  } finally {
    clearTimeout(timer);
  }
}

// Choisissez le bon hôte : voir tableau ci-dessus
checkHealth('http://10.0.2.2:3000/healthz');

Résultat attendu : status 200. Si l'erreur inclut TypeError: Network request failed, continuez ci-dessous.

3. Isoler DNS vs transport

Depuis votre machine de développement, résolvez et connectez-vous au nom d'hôte exact utilisé dans l'application.

macOS/Linux :

dig +short api.exemple.local
nc -vz api.exemple.local 3000

Windows (PowerShell) :

Resolve-DnsName api.exemple.local
Test-NetConnection api.exemple.local -Port 3000

Résultat attendu : le DNS renvoie au moins une adresse ; le test de port réussit. Si le DNS échoue mais que l'IP fonctionne, mettez à jour votre configuration d'application pour utiliser un hôte accessible (IP LAN pour le dev) ou corrigez les règles DNS à horizon partagé.

4. Vérifier l'accessibilité du port depuis le runtime d'appareil

  • L'émulateur Android hérite de l'accessibilité de l'hôte vers 10.0.2.2. Si vous vous connectez à une IP LAN à la place, assurez-vous que le pare-feu de l'hôte autorise l'entrant sur ce port.
  • Appareil Android physique : préférez adb reverse pour le développement local, ou ouvrez le pare-feu vers votre IP LAN et testez via http://<IP_LAN>.
  • Le simulateur iOS utilise le réseau de l'hôte ; localhost fonctionne.
  • Appareil iOS physique : assurez-vous du même Wi-Fi et ouvrez le pare-feu.

Vérifications pare-feu hôte

macOS (PF) :

sudo pfctl -s rules
lsof -iTCP -sTCP:LISTEN -P | grep 3000

Linux (UFW ou iptables) :

sudo ufw status verbose
sudo ss -ltnp | grep :3000

Windows :

Get-NetFirewallProfile
Get-NetFirewallRule | Select-String -Pattern 3000
netstat -ano | findstr :3000

Résultat attendu : votre processus serveur écoute, et le pare-feu autorise l'entrant sur la bonne interface.

5. Vérifier le routage et les proxys

Si un proxy système est configuré, les runtimes mobiles peuvent l'honorer.

macOS :

networksetup -getwebproxy Wi-Fi

Windows :

netsh winhttp show proxy

Linux :

env | egrep 'https?_proxy|HTTPS?_PROXY'

Résultat attendu : soit pas de proxy non intentionnel, soit des règles de proxy qui autorisent vos requêtes.

6. Observer les logs sur les échecs

Android :

adb logcat | egrep -i 'okhttp|ssl|connect|react|fatal'

Cherchez SSLHandshakeException, UnknownHostException, ou ConnectException.

iOS : ouvrez Console.app, filtrez sur votre processus, ou consultez les logs Xcode. Cherchez les codes NSURLErrorDomain tels que -1003 (hôte introuvable), -1200 (échec TLS), -1004 (impossible de se connecter à l'hôte), -1001 (timeout).

7. Vérification TLS

Utilisez l'URL https complète dans l'application et confirmez que la chaîne de certificats est valide pour l'appareil. Si vous utilisez une AC locale pour le dev, assurez-vous que l'AC est approuvée par l'appareil et, sur Android, autorisée par votre configuration de sécurité réseau debug.

8. Relance et backoff (résilience client)

Ajoutez des relances bornées pour les problèmes réseau transitoires.

async function retry(fn, retries = 2, base = 300) {
  let attempt = 0;
  while (true) {
    try { return await fn(); }
    catch (e) {
      if (attempt++ >= retries) throw e;
      const delay = base * Math.pow(2, attempt - 1);
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

await retry(() => checkHealth('http://10.0.2.2:3000/healthz'));

Résultat attendu : les échecs transitoires récupèrent en quelques tentatives. Les échecs persistants doivent quand même ressortir clairement.

Modes de défaillance et récupération

Utilisez ce mappage pour passer rapidement du symptôme au correctif.

Symptôme ou erreurCause probableCorrectif ciblé
ERR_NAME_NOT_RESOLVED, UnknownHostException, NSURLErrorDomain -1003Le DNS ne résout pas depuis le runtime d'appareilUtilisez le bon hôte pour le runtime (10.0.2.2, localhost, ou IP LAN). Corrigez le DNS ou utilisez l'IP LAN en dev.
ECONNREFUSED, impossible de se connecter, connexion refuséePort fermé ou serveur pas en écouteDémarrez le serveur, vérifiez l'adresse d'écoute 0.0.0.0, ouvrez le pare-feu, confirmez le port avec netstat/ss.
Timeout ou NSURLErrorDomain -1001Pare-feu, proxy, ou routage qui coupe ; serveur lentContournez le proxy, ouvrez le pare-feu, testez nc/Test-NetConnection, ajoutez un point de terminaison de santé serveur.
SSLHandshakeException, NSURLErrorDomain -1200Certificat invalide ou AC non approuvéeUtilisez HTTPS avec certificat valide, approuvez l'AC locale sur l'appareil, ajoutez une config de confiance debug-only sur Android.
Fonctionne dans le simulateur, échoue sur l'appareilMauvais hôte (localhost) ou isolation LANUtilisez l'IP LAN sur les appareils ; assurez-vous du même Wi-Fi ; envisagez adb reverse pour Android USB.
Problèmes réseau IPv6-onlyService accessible seulement via IPv4Assurez-vous que le DNS renvoie des AAAA ou utilisez dual-stack ; évitez les URLs littérales IPv4 en dur sur réseaux IPv6-only.
POST/PUT échouent, GET fonctionneLe serveur rejette en-têtes/taille du corpsInspectez les logs serveur ; ajustez Content-Type, corps, et limites serveur.
Croyance que CORS bloque les requêtesRN n'applique pas le CORS navigateurCorrigez la politique serveur si elle bloque Origin ; ce n'est pas une restriction client React Native.

Récupération et annulation

  • Supprimez les mappings adb reverse quand terminé :
adb reverse --remove-all
  • Annulez les relaxations réseau debug-only (manifeste Android, ATS iOS) avant tout build de production.
  • Si vous avez modifié des règles de pare-feu OS, documentez et revenez à la référence de l'équipe une fois les tests de développement terminés.
  • Si vous avez installé une AC locale sur des appareils pour le dev, supprimez-la des appareils non utilisés pour le développement.

Exemples pratiques

Basculer localhost vers le bon hôte par runtime

Émulateur Android :

const API = 'http://10.0.2.2:3000';

Simulateur iOS :

const API = 'http://localhost:3000';

Appareil physique sur LAN (remplacez par l'IP réelle) :

const API = 'http://192.168.1.50:3000';

Upload de fichier avec timeout explicite et surface d'erreur

async function uploadImage(uri) {
  const data = new FormData();
  data.append('file', { uri, type: 'image/jpeg', name: 'photo.jpg' });
  const controller = new AbortController();
  const t = setTimeout(() => controller.abort(), 15000);
  try {
    const res = await fetch(`${API}/upload`, {
      method: 'POST',
      body: data,
      headers: { 'Accept': 'application/json' },
      signal: controller.signal,
    });
    if (!res.ok) throw new Error(`Upload failed ${res.status}`);
    return await res.json();
  } finally {
    clearTimeout(t);
  }
}

Résultat attendu : réponse 200 ou 201 avec corps JSON ; sur annulation, affichez une erreur claire pour que l'utilisateur puisse réessayer.

Garde-fou de connectivité avant d'appeler les APIs

async function guardedFetch(url, init) {
  const s = await NetInfo.fetch();
  if (!s.isConnected || !s.isInternetReachable) {
    throw new Error('Pas de connexion internet');
  }
  return fetch(url, init);
}

Cela évite de spammer votre backend quand l'appareil est hors ligne.

Bibliothèque de commandes rapides

Utilisez ces commandes pour tester la résolution DNS et l'accessibilité des ports depuis votre machine de développement.

OSVérification DNSVérification portNotes
macOSdig +short hote.exemplenc -vz hote.exemple 3000Utilisez aussi scutil --dns pour détails resolveurs.
Linuxgetent hosts hote.exemplenc -vz hote.exemple 3000resolvectl status pour DNS par liaison.
WindowsResolve-DnsName hote.exempleTest-NetConnection hote.exemple -Port 3000Ajoutez -InformationLevel Detailed pour plus de sortie.

Résultats attendus

  • La vérification DNS renvoie au moins une IP.
  • La vérification port rapporte succès ; sinon, investiguez pare-feu, adresse d'écoute, ou routage.

Liste de contrôle opérationnelle

Utilisez cette liste répétable sur chaque problème réseau React Native.

  • Inventaire
  • Enregistrez RN, OS, appareil/émulateur, et URLs et ports du backend.
  • Notez statut VPN/proxy et pare-feu.
  • Choisir un pilote
  • Choisissez un runtime (ex. émulateur Android) et un point de terminaison de santé.
  • Configurer en sécurité
  • Utilisez l'hôte correct (10.0.2.2, localhost, ou IP LAN).
  • Optionnellement utilisez adb reverse pour le développement Android.
  • Ajoutez les relaxations réseau debug-only si absolument requis ; documentez-les.
  • Vérifier étape par étape
  • Vérifiez la connectivité NetInfo depuis l'application.
  • Faites une requête HEAD avec timeout 5s ; attendez 200.
  • Depuis votre machine, résolvez le DNS et testez le port.
  • Confirmez que le serveur écoute et que le pare-feu autorise l'entrant.
  • Observer les logs
  • Android : adb logcat pour erreurs okhttp/ssl/connect.
  • iOS : Xcode ou Console pour codes NSURLErrorDomain.
  • Corriger par mode de défaillance
  • Mauvais hôte : utilisez l'hôte approprié au runtime.
  • Port fermé : démarrez le serveur, écoutez sur 0.0.0.0, ouvrez le pare-feu.
  • DNS cassé : utilisez l'IP LAN en dev ou corrigez le DNS.
  • TLS cassé : approuvez l'AC de dev ou utilisez certificats valides ; supprimez les relaxations après.
  • Annuler
  • Supprimez les mappings adb reverse.
  • Supprimez les exceptions réseau debug-only.
  • Revenez aux règles de pare-feu de référence de l'équipe.

Conclusion

Le réseau React Native devient prévisible quand vous le traitez comme une séquence d'étapes observables : inventaire, choix d'un pilote étroit, application d'une configuration sûre et réversible, vérification depuis le runtime réel, et expansion seulement après un test vert net. Avec la bonne sélection d'hôte, des tests DNS et port clairs, et des logs ciblés, vous pouvez isoler les problèmes en minutes au lieu de jours. Gardez les relaxations de développement strictement debug-only, documentez chaque changement, et annulez-les dès que vos vérifications passent. Cette approche s'échelonne du développeur individuel aux équipes de démarrage et mandats de conseil tout en gardant le risque bas et les résultats mesurables.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO