web-dev-qa-db-ja.com

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

react-native init(RNバージョン0.29.1)を使用してまったく新しいプロジェクトを作成し、その公開メソッドをpublic facebookデモムービーAPIにフェッチすると、Network Request Failedがスローされます。非常に無駄なスタックトレースがあり、クロムコンソールでネットワーク要求をデバッグできません。これが私が送っているフェッチです:

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

ここでの問題は、iOSはデフォルトではHTTPリクエストを許可しないで、HTTPSだけを許可することです。 HTTPリクエストを有効にしたい場合は、これをinfo.plistに追加してください。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
127
Alek Hurst

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

出典: iOS 9とOSX 10.11でのApp Transportセキュリティ例外の設定

以下をアプリの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>
53
Lavi Avigdor

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

編集

Android Emulatorでは、開発マシンのアドレスは10.0.2.2です。より多くの説明 ここ

Genymotionの場合、アドレスは10.0.3.2です。より多くの情報 ここ

15
Mahmoodvcs

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>

ネイティブドキュメントとの反応 - >既存のアプリケーションとの統合 - >統合のテスト - > App Transport Securityの例外の追加

8
Ocean Liu

問題はサーバー構成にあります。

Android 7.0にはバグがあります ここに記述されている 。回避策はVicky Chijwaniによって提案されました:

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

7
Dmitry Maksakov

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

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

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

Androidユーザーの場合:

  1. Androidデバイスでプロジェクトを実行すると、localhostはコンピューターの代わりにAndroidデバイスを指しているため、localhostsをLan IPアドレスに置き換えます。例:change http://localostからhttp://192.168.1.123

  2. リクエストURLがHTTPSで、Androidデバイスがプロキシの下にある場合、Androidデバイスにユーザー追加CA(burpスイートのCAやCharles's CAなど)がインストールされていると仮定します。 Androidバージョンが以下であることを確認してくださいNougat(7.0)、理由は次のとおりです。 Android Nougat

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

2
fangxing

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

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

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

URL- http://10.106.105.103/authToken.json - うまくいきました:):D

注 - マシンのIpAddressを見つけるには、Linuxではifconfig、Windowsではipconfigを使用してください。

2
Varun Kumar

私は同様の問題を抱えています。私の場合、localhostへのリクエストは機能していて突然停止しました。それは問題は私が私のAndroid携帯電話上の私の無線LANをオフにしていたということだったことが判明した。

Androidの場合、AndroidManifest.xmlに権限を追加し忘れている可能性があります。以下の権限を追加する必要があります。

<uses-permission Android:name="Android.permission.INTERNET" /> 
2
Shashwat

これは私のために働いた、Androidは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
Cho Cho

REST apiにdockerを使用する場合、私の場合はhostname:http://demo.test/apiをマシンのipアドレス:http://x.x.x.x/apiに置き換えることでした。あなたは、あなたがあなたの無線ネットワークで持っているipv4をチェックすることからIPを得ることができます。あなたは携帯電話からの無線LANも持っている必要があります。

1
Craciun Ciprian

フェッチ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
user3374790

あなたは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

私は有効な証明書を使って外部のHTTPS URLにアクセスしようとしたAndroid Emulatorで同じ問題に出会いました。しかし、そのネイティブ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 Rem remote'を有効にしました

2)報告されたエラーは

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

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

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

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

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

ネットワークセキュリティ設定ファイル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>

これはうまくいくはずであり、あなたに期待される反応を与えるはずです。

0
henryoats