React Native fetch()ネットワーク要求が失敗しました


146

react-native init(RNバージョン0.29.1)を使用して真新しいプロジェクトを作成し、renderメソッドでフェッチをpublic facebookデモムービーAPIに入れると、がスローされますNetwork Request Failed。非常に役に立たないスタックトレースがあり、Chromeコンソールでネットワークリクエストをデバッグできません。これが私が送信しているフェッチです:

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

1
よく分かりません。私はiOSシミュレーターを使用していて、コンピューターのインターネット接続を使用していると思いました
Alek Hurst

シミュレータを手動でロードして、サファリでURLを開いてみてください
FuzzyTree

5
http-> https(可能な場合)問題を解決する可能性が最も高い
Nick Zuber

1
サーバーをそのIPにバインドせずにIP 192.168.1.25:3000from ifconfigを使用していたrails server --binging=192.168.1.25 --port=3000
Fabrizio Bertoglio

1
はい、すべて試しました。何もうまく
いかなかった

回答:


140

ここでの問題は、iOSではデフォルトでHTTPリクエストが許可されず、HTTPSのみが許可されることです。HTTPリクエストを有効にしたい場合は、これを以下に追加しますinfo.plist

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

2
この答えは私にとってうまくいきました。ネイティブを反応させるために、新たな他の人のために、このファイル(Info.plistファイル)も、Xcodeの経由で編集することができます:stackoverflow.com/a/38219454/1299792
Marklar

86
アンドロイドはどうですか?私はアンドロイドでも同じ問題に直面しています。
Vijay Sharma

16
丁度。誰もがアンドロイドの答えを持っていますか?
ザッククック

1
それをios / build / info.plistに置いて実行すると、次のようになります。react-native run-ios ios / build / info.plistが上書きされ、変更が中止されます。どうすればよいですか?
Jorge Wander SantanaUreña2017年

1
@JorgeWanderSantanaUreñamodify [your_project_folder_name] / ios / [your_project_folder_name] / In‌ fo.plist
kgosse

58

すべてのドメインにhttpを許可することはお勧めしません。必要なドメインだけを例外にします。

出典:iOS 9およびOSX 10.11でのApp Transport Security例外の構成

アプリのinfo.plistファイルに以下を追加します。

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

27
アンドロイドはどうですか?
arisalexis 2016年

3
React Nativeアプリの複数のディレクトリに複数のinfo.plistファイルがあるようです。どのフォルダに変更する正しいファイルが含まれているのでしょうか?
Marklar、2017

2
@Marklar [your_project_folder_name] / ios / [your_project_folder_name] /Info.plist
Stich

ここでlocalhostを使用する場合:<key> yourserver.com </ key>、公開する準備ができたら、変更する必要がありますよね?
Anayo Oleru

36

localhost明らかに間違っていたアドレスに使用していた。サーバーのIPアドレス(エミュレーターが存在するネットワーク内)に置き換えた後、完全に機能しました。

編集する

Android Emulatorでは、開発マシンのアドレスは10.0.2.2です。詳細はこちら

Genymotionの場合、アドレスは10.0.3.2です。詳細はこちら


4
ありがとうございました。おそらく、Androidで機能する唯一の応答です。私のネットワークのIPアドレスを使用し、それは動作します。例http://<Network IP emulator connects to>:<port where API is served>/api/tasks
Brandon Benefield、

1
"http://"を忘れないでください。そうしないと機能しません...なぜそれが郵便配達員では機能するが、フェッチでは機能しないのか疑問に思っていました
Moucheg

@Mahmoodvcsあなたの答えは私を助けてくれます。本当にありがとうございます。私はAndroidエミュレータを使用しています。
Pena Pintada

14

私たちにとっては、ファイルをアップロードしていて、RN filePickerが適切なMIMEタイプを提供しなかったためです。タイプとして「イメージ」を提供するだけです。フェッチを機能させるには、これを「image / jpg」に変更する必要がありました。

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

@JohhanSantanaおそらく生の画像データを見て最初からそれを取得できますが、reactネイティブピッカーが「画像」を返してきました。
NickJ

10

React Native Docsがこれに対する答えを提供します。

Appleは暗黙のクリアテキストHTTPリソースの読み込みをブロックしました。したがって、次のプロジェクトのInfo.plist(または同等の)ファイルを追加する必要があります。

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

React Native Docs->既存のアプリとの統合->統合のテスト-> App Transport Security例外の追加


9

サーバーの構成に問題がある可能性があります。

Android 7.0には、ここで説明するバグがあります。Vicky Chijwaniによって提案された回避策:

楕円曲線prime256v1を使用するようにサーバーを構成します。たとえば、Nginx 1.10では、ssl_ecdh_curve prime256v1を設定してこれを行います。


7

Androidでも同じ問題が発生しましたが、解決策を見つけることができました。Androidは、デフォルトでAPIレベル28以降のクリアテキストトラフィック(非httpsリクエスト)をブロックしています。ただし、react-native android/app/src/debug/res/xml/react_native_config.xmlは一部のドメイン(localhost、およびAVD / GenymotionのホストIP)を定義するデバッグバージョン()にnetwork-security-configを追加します。これは、開発モードでSSLなしで使用できます。ここにドメインを追加して、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>

これは、reactネイティブ0.59とターゲットSDK 28で私にとっては
うまくいきました

7

「http」が原因でAndroid 9でも同じ問題が発生し、AndroidManifest.xmlにandroid:usesCleartextTraffic = "true"を追加するだけで問題が解決しました

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


2
おかげで、これも私にとってはうまくいきました。AndroidはAPI 28にデフォルトごとにもうHTTPをサポートしていないので、それは起こる
桂ヘルツォークに

5

Android Emulatorで同じ問題に遭遇しましたが、有効な証明書で外部HTTPS URLにアクセスしようとしました。しかし、そのURLを反応ネイティブでフェッチすることに失敗しました

'fetch error:', { [TypeError: Network request failed]
sourceURL: 'http://10.0.2.2:8081/index.delta?platform=android&dev=true&minify=false' }

1)ログで正確なエラーを見つけるために、最初にアプリでCmd + Mを使用して「Debug JS Remotely」を有効にしました

2)報告されたエラーは

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

3)この方法でURLの有効な証明書を追加しました->ステップ2

http://lpains.net/articles/2018/install-root-ca-in-android/

この証明書は[ユーザー]タブに追加されます。

4)属性android:networkSecurityConfig属性をAndroidManifest.xmlに追加します

ネットワークセキュリティ構成ファイルを追加する 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>

これで問題が解決し、期待どおりの応答が得られます。


作業するためには、手順4を実行する必要がありました。ありがとう!
Bruno Serrano

4

私はAndroidでこの問題を抱えていました-

URL- localhost / authToken.json-動作しませんでした:(

URL- 10.106.105.103/authToken.json-動作しませんでした:(

URL- http://10.106.105.103/authToken.json-機能しました:):D

注-Linux ifconfigまたはipconfigWindowsでマシンIpAddressを検索するために使用します


4

Androidユーザーの場合:

  1. 交換してくださいlocalhost、あなたは、Androidデバイス上でプロジェクトを実行すると、ローカルホストではなく、コンピュータの、Androidデバイスを指しているので、LANのIPアドレスにSを、例:変更http://localosthttp://192.168.1.123

  2. あなたの要求のURLがHTTPSであり、あなたのAndroidデバイスがプロキシの下にある場合、あなたはユーザーを追加CAインストールされていると仮定し、あなたのAndroidデバイスで(げっぷスイートのCAやチャールズのCAのように)、必ずお使いのAndroidのバージョンは以下で作るヌガー(7.0)ので、 :Android Nougatの信頼できる認証局の変更

    ユーザーが追加したCA
    すべてのアプリケーションデータの保護は、Androidアプリケーションサンドボックスの主要な目標です。Android Nougatは、アプリケーションがユーザー提供および管理者提供のCAと対話する方法を変更します。デフォルトでは、アプリが明示的にオプトインしない限り、APIレベル24をターゲットとするアプリは、設計上、このようなCAを尊重しません。


3

Androidの場合、AndroidManifest.xmlに権限を追加するのに失敗した可能性があります。次の権限を追加する必要があります。

<uses-permission android:name="android.permission.INTERNET" /> 

そのエラーが発生しているにもかかわらず、すでにそれはありますが、他の回避策はありますか?
masud_moni

@masud_moniあなたは問題を修正する方法を見つけましたか?

@RafaelRotirotiはい私はその問題を解決しましたが、しばらくは覚えていませんが、許可を使用していてまだ問題が発生している場合は、詳細を共有してください。私は最善を尽くしてお手伝いします。他の人にも調べて
もらい

@masud_moniありがとう、ifconfigコマンドの実行後に指定されたIPを使用してその問題を修正しました。AVDは仮想デバイスを作成するため、デバイスの127.0.0.1でホストされていない仮想マシンと同じ理論を使用します。したがって、私は192.168.xx IPを使用し、すべてが正常に動作します
Rafael Rotiroti '31

2

同様の問題があります。私の場合、localhostへのリクエストは機能していて、突然停止しました。問題は、AndroidフォンでWi-Fiをオフにすることでした。


2

これは私にとってはうまくいきました、アンドロイドは特別なタイプのIPアドレス10.0.2.2を使用してからポート番号を使用します

import { Platform } from 'react-native';

export const baseUrl = Platform.OS === 'android' ?
    'http://10.0.2.2:3000/'
: 
'http://localhost:3000/';

1

REST APIにdockerを使用する場合、私にとっての作業例は、ホスト名:http://demo.test/apiをマシンのIPアドレス: に置き換えることでしたhttp://x.x.x.x/api。ワイヤレスネットワーク上にあるipv4を確認することで、IPを取得できます。あなたも電話からの無線LANを持っている必要があります。


1

フェッチAPIの場合は、.thenでエラーケースを処理する必要があります。

例えば:

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
  1. android:usesCleartextTraffic="true"AndroidManifest.xml に行を追加します。

  2. Androidフォルダーからすべてのデバッグフォルダーを削除します。


0

あなたはこれを使ってそれを扱うことができます:

catch((error) => {
      this.setState({
        typing_animation_button: false,
      });
      console.log(error);
      if ('Timeout' || 'Network request failed') {
        toast_show = true;
        toast_type = 'error';
        toast_text = 'Network failure';
      }
      this.setState({
        disable_button: false,
      });
    });

-1

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

-1

Androidデバイスの場合は、プロジェクトのルートフォルダーに移動して、次のコマンドを実行します。

adb reverse tcp:[your_own_server_port] tcp:[your_own_server_port]

例えば、 adb reverse tcp:8088 tcp:8088

これにより、物理デバイス(つまりAndroidフォン)は、アドレスhttp:// localhost:[your_own_server_port]で開発マシン(つまりコンピューター)で実行されているlocalhostサーバーをリッスンします。

その後http:localhost:[your_port] /your_api、react-native fetch()呼び出しで直接使用できます。


-1

androidの場合、次のように、android:networkSecurityConfig = "@ xml / network_security_config"をAndroidManifest.xmlのアプリケーションタグに追加します。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest ... >
        <application android:networkSecurityConfig="@xml/network_security_config"
                        ... >
            ...
        </application>
    </manifest>

network_security_config.xmlファイルの内容:

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

詳しく説明してください。私はそれがどのように機能するのか興味がありますか?
ganeshdeshmukh

役立つコメント、希望変更しました
XYZ

-5

例:

return fetch('http://<your ip>')
  .then((response) => response.json())
  .then((responseJson) => {
    console.log(responseJson)
  })
  .catch((error) => {
    console.error(error);
  });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.