React Native fetch()网络请求失败

2020/11/07 15:23 · javascript ·  · 0评论

当我使用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或ipconfigWindows上使用以查找计算机IpAddress

对于Android用户:

  1. 替换localhost,因为当您运行在Android设备上的项目,本地主机是指向Android设备s到局域网的IP地址,而不是你的电脑,例如:改变http://localosthttp://192.168.1.123

  2. 如果您的请求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

访问此链接以获取更多信息。

  1. android:usesCleartextTraffic="true"在AndroidManifest.xml中添加一行。

  2. 从您的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>
本文地址:http://javascript.askforanswer.com/react-native-fetchwangluoqingqiushibai.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!