当我使用react-native init
(RN版本0.29.1)创建一个全新的项目并将抓取放入公共Facebook演示电影API的render方法中时,它会抛出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);
});
这里的问题是,iOS默认情况下不允许HTTP请求,仅允许HTTPS。如果要启用HTTP请求,请将其添加到您的info.plist
:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
不建议允许所有域都使用http。仅对必要的域进行例外处理。
来源:在iOS 9和OSX 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>
我使用localhost
的是地址,这显然是错误的。将其替换为服务器的IP地址(在仿真器所在的网络中)后,它可以正常工作。
编辑
在Android Emulator中,开发计算机的地址为10.0.2.2
。在这里更多的解释
对于Genymotion,地址为10.0.3.2
。更多信息在这里
对我们来说,这是因为我们正在上传文件,而RN filePicker没有提供正确的mime类型。它只是给我们“形象”作为类型。我们需要将其更改为“ image / jpg”以使提取工作。
form.append(uploadFileName, {
uri : localImage.full,
type: 'image/jpeg',
name: uploadFileName
})
我在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>
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->与现有应用程序集成->测试您的集成->添加应用程序传输安全性例外
问题可能出在服务器配置中。
Android 7.0此处描述了一个错误。Vicky Chijwani提出的解决方法:
配置服务器以使用椭圆曲线prime256v1。例如,在Nginx 1.10中,您可以通过设置ssl_ecdh_curve prime256v1来实现;
我在Android上遇到了同样的问题,但设法找到了解决方案。自默认启用API级别28以来,Android禁止明文流量(非https请求)。但是,react-native将网络安全配置添加到调试版本(android/app/src/debug/res/xml/react_native_config.xml
),该版本定义了某些域(本地主机和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>
我在Android Emulator上遇到了相同的问题,在该问题中,我尝试使用有效的证书访问外部HTTPS URL。但是在react-native中获取该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启用了“远程调试JS”
2)报告的错误是
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
3)我使用此方法->步骤2添加了URL的有效证书
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>
这应该起作用,并给您预期的响应。
我在Android上遇到这个问题-
URL- localhost / authToken.json-不起作用:(
URL- 10.106.105.103/authToken.json-不起作用:(
URL- http://10.106.105.103/authToken.json -工作:):d
注-ifconfig
在Linux或ipconfig
Windows上使用以查找计算机IpAddress
对于Android用户:
-
替换
localhost
,因为当您运行在Android设备上的项目,本地主机是指向Android设备s到局域网的IP地址,而不是你的电脑,例如:改变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,除非该应用程序明确选择加入。此默认安全设置减少了应用程序的攻击面,并鼓励对网络和基于文件的应用程序数据进行一致的处理。
对于Android,您可能错过了在AndroidManifest.xml中添加权限的权限。需要添加以下权限。
<uses-permission android:name="android.permission.INTERNET" />
我有类似的问题。在我的情况下,对localhost的请求正在工作,并且突然停止。事实证明,问题是我关闭了Android手机上的wifi。
这对我有用,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/';
如果您将docker用于REST api,对我来说,一个可行的例子是将hostname:替换http://demo.test/api
为机器的IP地址: http://x.x.x.x/api
。您可以通过检查无线网络上的ipv4来获取IP。您还应该从电话上获得wifi。
您应该在.then中处理错误情况以获取API。
例如:
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.0.0.0上运行模拟服务器
注意:当您使用json-server运行另一台服务器时,这在Expo上有效。
另一种方法是在0.0.0.0而不是localhost或127.0.0.1上运行模拟服务器。
这使得模拟服务器可以在LAN上访问,并且因为Expo要求开发机器和运行Expo应用程序的移动设备位于同一网络上,所以模拟服务器也可以访问。
使用json-server时,可以使用以下命令来实现
json-server --host 0.0.0.0 --port 8000 ./db.json --watch
访问此链接以获取更多信息。
-
android:usesCleartextTraffic="true"
在AndroidManifest.xml中添加一行。 -
从您的android文件夹中删除所有调试文件夹。
您可以使用以下方法处理它:
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,
});
});
这不是答案,而是选择。我切换到https://github.com/joltup/rn-fetch-blob
对于表单数据和文件都很好
解决方案是简单更新nodejs版本14或更高版本
就我而言,Android仿真器未连接到Wi-Fi。
在这里看到Android Studio-没有互联网连接的Android Emulator Wifi
只是您有获取中的更改...。
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);
});
对于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-nativefetch(
调用中使用。
对于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>
文章标签:fetch-api , javascript , react-native
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!