javascript - React Native fetch() Zahtjev mreže nije uspio


Kada kreiram potpuno novi projekt koristeći react-native init (RN verzija 0.29.1) i stavim fetch u render metodu prema javnom facebook demo movie API-ju, pojavljuje se Network Request Failed. Postoji vrlo beskorisno praćenje stoga ne mogu debugirati mrežne zahtjeve u chrome konzoli. Ovo je fetch koji šaljem:

fetch('http://facebook.github.io/react-native/movies.json')
      .then((response) => response.json())
      .then((responseJson) => {
        return responseJson.movies;
      })
      .catch((error) => {
        console.error(error);
      });

Odgovor #1

Problem ovdje je što iOS prema zadanim postavkama ne dopušta HTTP zahtjeve, samo HTTPS. Ako želite omogućiti HTTP zahtjeve, dodajte ovo u svoj info.plist:

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

Odgovor #2

Koristio sam localhost za adresu, što je očito bilo pogrešno. Nakon što sam ga zamijenio IP adresom servera (u mreži u kojoj se emulator nalazi), radilo je savršeno.

Uredi

U Android emulatoru, adresa razvojne računala je 10.0.2.2. Više objašnjenja ovdje

Za Genymotion, adresa je 10.0.3.2. Više informacija ovdje

Odgovor #3

Nije preporučeno dopuštati sve domene za http. Napravite iznimku samo za potrebne domene.

Izvor: Konfiguriranje iznimki za App Transport Security u iOS-u 9 i OSX-u 10.11

Dodajte sljedeće u datoteku info.plist vaše aplikacije:

<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>

Odgovor #4

Imao sam isti problem na Androidu 9 zbog "http" i problem je riješen jednostavnim dodavanjem android:usesCleartextTraffic="true" u 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>

Odgovor #5

Za nas je to bilo zato što smo učitavali datoteku i RN filePicker nije dao odgovarajući MIME tip. Davao nam je samo 'image' kao tip. Trebali smo to promijeniti u 'image/jpg' da bi fetch radio.

form.append(uploadFileName, {
  uri : localImage.full,
  type: 'image/jpeg',
  name: uploadFileName
 })

Odgovor #6

ako koristiš localhost, samo ga promijeni :

od :http://localhost:3030 do :http://10.0.2.2:3030

Odgovor #7

Imao sam isti problem na Androidu, ali uspio sam pronaći rješenje za njega. Android po difaultu blokira nešifrirani promet (zahtjeve koji nisu https) od API razine 28 naviše. Međutim, react-native dodaje network-security-config u debug verziju (android/app/src/debug/res/xml/react_native_config.xml) koja definira neke domene (localhost i IP adrese hosta za AVD/Genymotion), koje se mogu koristiti bez SSL-a u developerskom režimu. Tamo možete dodati svoju domenu kako biste omogućili http zahtjeve.

<?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>

Odgovor #8

Za korisnike Androida:

  1. Zamijenite localhost s LAN IP adresama jer kada pokrenete projekt na Android uređaju, localhost pokazuje na Android uređaj, umjesto na vaše računalo, primjer: promijenite http://localhost u http://192.168.1.123

  2. Ako je URL vaše zahtjeva HTTPS i vaš Android uređaj je ispod proxyja, pretpostavite da ste instalirali CA dodanu od strane korisnika (poput Burp Suite CA ili Charles CA) na svom Android uređaju, pobrinite se da je vaša verzija Androida ispod Nougat(7.0), jer: Promjene u pouzdanim certifikacijskim autoritetima u Android Nougatu

    Korisnikom dodani CA
    Zaštita svih podataka aplikacije ključni je cilj Android aplikacijskog sandboksa. Android Nougat mijenja način na koji aplikacije komuniciraju s CA-ima koje pruža korisnik ili administrator. Zadano, aplikacije koje ciljaju API razinu 24—po dizajnu—neće poštovati takve CA-e osim ako aplikacija izričito ne odabere da ih koristi. Ova zadana postavka koja osigurava sigurnost smanjuje površinu za napade na aplikaciju i potiče dosljedno rukovanje mrežnim i datotečnim podacima aplikacije.

Odgovor #9

React Native dokumentacija daje odgovor na ovo.

Apple je blokirao implicitno učitavanje HTTP resursa u običnom tekstu. Stoga moramo dodati sljedeće u datoteku Info.plist našeg projekta (ili ekvivalentnu datoteku).

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

React Native dokumentacija -> Integracija s postojećim aplikacijama -> Testirajte svoju integraciju -> Dodajte iznimku za App Transport Security

Odgovor #10

Problem može biti u konfiguraciji poslužitelja.

Android 7.0 ima bug opisan ovdje. Rješenje predloženo od strane Vicky Chijwani:

Konfigurirajte svoj poslužitelj da koristi eliptičnu krivulju prime256v1. Na primjer, u Nginxu 1.10 to radite postavljanjem ssl_ecdh_curve prime256v1;

Odgovor #11

Imao sam ovaj problem s Androidom

URL- localhost/authToken.json - nije radilo :(

URL- 10.106.105.103/authToken.json - nije radilo :(

URL- http://10.106.105.103/authToken.json - uspjelo :) :D

Napomena - Koristite ifconfig na Linuxu ili ipconfig na Windowsu kako biste pronašli IP adresu računala

Povezani članci