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);
});
ここでの問題は、iOSはデフォルトではHTTPリクエストを許可しないで、HTTPSだけを許可することです。 HTTPリクエストを有効にしたい場合は、これをinfo.plist
に追加してください。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
すべてのドメインに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>
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の例外の追加
問題はサーバー構成にあります。
Android 7.0にはバグがあります ここに記述されている 。回避策はVicky Chijwaniによって提案されました:
楕円曲線prime256v1を使用するようにサーバーを構成します。たとえば、Nginx 1.10では、ssl_ecdh_curve prime256v1を設定してこれを行います。
私たちにとっては、ファイルをアップロードしようとしていて、RNのfilePickerが適切なMIMEタイプを与えていないためです。それはただタイプとして私達に「イメージ」を与えました。フェッチを機能させるには、それを 'image/jpg'に変更する必要があります。
form.append(uploadFileName, {
uri : localImage.full,
type: 'image/jpeg',
name: uploadFileName
})
私は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>
Androidユーザーの場合:
Androidデバイスでプロジェクトを実行すると、localhostはコンピューターの代わりにAndroidデバイスを指しているため、localhost
sをLan IPアドレスに置き換えます。例:change http://localost
からhttp://192.168.1.123
ユーザーが追加したCA
すべてのアプリケーションデータの保護は、Androidアプリケーションサンドボックスの主要な目標です。 Android Nougatは、アプリケーションがユーザー提供および管理者提供のCAと対話する方法を変更します。デフォルトでは、APIレベル24をターゲットとするアプリは、アプリが明示的にオプトインしない限り、設計によりそのようなCAを尊重しません。
私は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
を使用してください。
私は同様の問題を抱えています。私の場合、localhostへのリクエストは機能していて突然停止しました。それは問題は私が私のAndroid携帯電話上の私の無線LANをオフにしていたということだったことが判明した。
Androidの場合、AndroidManifest.xmlに権限を追加し忘れている可能性があります。以下の権限を追加する必要があります。
<uses-permission Android:name="Android.permission.INTERNET" />
これは私のために働いた、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/';
REST apiにdockerを使用する場合、私の場合はhostname:http://demo.test/api
をマシンのipアドレス:http://x.x.x.x/api
に置き換えることでした。あなたは、あなたがあなたの無線ネットワークで持っているipv4をチェックすることからIPを得ることができます。あなたは携帯電話からの無線LANも持っている必要があります。
フェッチ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;
});
あなたは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);
});
私は有効な証明書を使って外部の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>
これはうまくいくはずであり、あなたに期待される反応を与えるはずです。