javascript - React Native fetch() 網路請求失敗
當我使用 react-native init(RN 版本 0.29.1)創建一個全新的專案,並在 render 方法中放置一個對公共 Facebook 範例電影 API 的 fetch 時,它會拋出 Network Request Failed。有一個非常無用的堆疊追蹤,並且我無法在 Chrome 控制台中調試網絡請求。這是我發出的 fetch:
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 預設不允許 HTTP 請求,只允許 HTTPS。如果你想啟用 HTTP 請求,請將以下內容添加到你的 info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
答案#2
我使用的是 localhost 作為地址,但這顯然是錯的。將它替換為伺服器的 IP 地址(在模擬器所在的網路中)後,它工作得非常完美。
編輯
在 Android 模擬器中,開發機的地址是 10.0.2.2。更多說明請參見這裡
對於 Genymotion,地址是 10.0.3.2。更多資訊在這裡
答案#3
不建議允許所有網域使用 http。僅對必要的網域例外處理。
來源:在 iOS 9 和 OS X 10.11 中配置應用傳輸安全例外
將以下內容添加到您應用程式的 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>
答案#4
我在 Android 9 上遇到了相同的問題,原因是「http」,問題通過只在 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>
答案#5
對我們來說,原因是我們正在上傳一個文件,而 RN filePicker 沒有提供正確的 mime 類型。它只給了我們 'image' 作為類型。我們需要將其更改為 'image/jpg' 才能讓 fetch 正常工作。
form.append(uploadFileName, {
uri : localImage.full,
type: 'image/jpeg',
name: uploadFileName
})
答案#6
如果你使用本地主機,只需更改它:
從:http://localhost:3030 到:http://10.0.2.2:3030
答案#7
我在 Android 上也遇到了同樣的問題,但我設法找到了解決方法。從 API Level 28 開始,Android 默認會阻擋明文流量(非 HTTPS 請求)。然而,react-native 在調試版本中添加了一個 network-security-config(android/app/src/debug/res/xml/react_native_config.xml),其中定義了一些域名(localhost,以及 AVD/Genymotion 的主機 IP),這些域名在開發模式下可以不使用 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>
答案#8
適用於 Android 用戶:
將
localhost替換為局域網 IP 地址,因為當你在 Android 設備上運行專案時,localhost 指向的是 Android 設備,而不是你的電腦,例如:將http://localost改為http://192.168.1.123如果您的請求 URL 為 HTTPS 且您的 Android 設備位於代理下,假設您已在 Android 設備上安裝了用戶添加的 CA(例如 Burp Suite 的 CA 或 Charles 的 CA),請確保您的 Android 版本低於 Nougat(7.0),因為:Android Nougat 中受信任的證書權限變更
使用者新增的憑證授權 (CA)
保護所有應用程式資料是 Android 應用程式沙盒的一個重要目標。Android Nougat 改變了應用程式與使用者及管理員提供的 CA 的互動方式。預設情況下,針對 API 級別 24 的應用程式設計上不會認可這些 CA,除非應用程式明確選擇啟用。這種預設安全設定降低了應用程式的攻擊面,並鼓勵對網路及檔案型應用程式資料的一致處理。
答案#9
React Native 文件提供了這個問題的答案。
蘋果已經阻止了隱式明文 HTTP 資源加載。因此我們需要將以下內容添加到我們專案的 Info.plist(或等效)文件中。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
React Native 文件 -> 與現有應用整合 -> 測試您的整合 -> 添加應用傳輸安全例外
答案#10
問題可能出在伺服器配置上。
Android 7.0 有一個在這裡描述的錯誤。Vicky Chijwani 提出的解決方法:
將您的伺服器配置為使用橢圓曲線 prime256v1。例如,在 Nginx 1.10 中,您可以通過設置 ssl_ecdh_curve prime256v1; 來實現這一點。
答案#11
我在 Android 上遇到這個問題。
URL- localhost/authToken.json - 不管用 :(
URL- 10.106.105.103/authToken.json - 無法使用 :(
URL- http://10.106.105.103/authToken.json - 成功了 :) :D
注意-在 Linux 上使用 ifconfig 或在 Windows 上使用 ipconfig 來查找機器的 IP 位址
