Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React Native fetch()网络请求失败_Javascript_React Native_Fetch Api - Fatal编程技术网

Javascript React Native fetch()网络请求失败

Javascript React Native fetch()网络请求失败,javascript,react-native,fetch-api,Javascript,React Native,Fetch Api,当我使用react native init(RN版本0.29.1)创建一个全新的项目,并在呈现方法中将一个fetch放入公共facebook演示电影API时,它抛出一个网络请求失败。有一个非常无用的堆栈跟踪,我无法在chrome控制台中调试网络请求。这是我要发送的回执: fetch('http://facebook.github.io/react-native/movies.json') .then((response) => response.json()) .t

当我使用
react native init
(RN版本0.29.1)创建一个全新的项目,并在呈现方法中将一个fetch放入公共facebook演示电影API时,它抛出一个
网络请求失败
。有一个非常无用的堆栈跟踪,我无法在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>
NSAppTransportSecurity
NSAllowsArbitraryLoads

不建议允许http的所有域。 仅对必要的域进行例外

资料来源:

将以下内容添加到应用程序的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>
NSAppTransportSecurity
NSExceptionDomains
yourserver.com
n包括多个域
NSTemporary ExceptionalLowsInSecureHttpLoads
NSTemporaryExceptionMinimumTLSVersion
TLSv1.1

只要您在获取中有更改

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);
     });

React Native Docs对此给出了答案

苹果已阻止隐式明文HTTP资源加载。因此,我们需要添加以下项目的Info.plist(或等效)文件

NSAppTransportSecurity
NSExceptionDomains
本地服务器
NSTemporary ExceptionalLowsInSecureHttpLoads

对于Android,您可能没有在AndroidManifest.xml中添加权限 需要添加以下权限

<uses-permission android:name="android.permission.INTERNET" /> 

问题可能出在服务器配置中

安卓7.0有一个bug。Vicky Chijwani提出的解决方案:

将服务器配置为使用椭圆曲线prime256v1。对于 例如,在nginx1.10中,可以通过设置ssl\u ecdh\u曲线来实现这一点 prime256v1


我使用了
localhost
作为地址,这显然是错误的。在用服务器的IP地址(在emulator所在的网络中)替换它之后,它工作得非常好

编辑

在Android Emulator中,开发机器的地址是
10.0.2.2
。更多解释

对于Genymotion,地址是
10.0.3.2
。更多信息

我也有类似的问题。 在我的例子中,对localhost的请求正在工作,并突然停止。
原来问题是我在android手机上关闭了wifi。

我在android手机上遇到了这个问题-

URL-localhost/authToken.json-不起作用:(

URL-10.106.105.103/authToken.json-不起作用:(

URL--已工作:):D


注意-在Linux上使用
ifconfig
,或在Windows上使用
ipconfig
来查找计算机IpAddress

对我们来说,这是因为我们上载了一个文件,而RN文件选择器没有给出正确的mime类型。它只给了我们“image”作为类型。我们需要将其更改为“image/jpg”以使提取工作

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

对于Android用户:

  • localhost
    s替换为Lan IP地址,因为在Android设备上运行项目时,localhost指向的是Android设备,而不是您的计算机,例如:change
    http://localost
    http://192.168.1.123

  • 如果您的请求URL为HTTPS且您的Android设备处于代理之下,则假设您已在Android设备中安装了用户添加的CA(如burp suite的CA或Charles的CA),请确保您的Android版本低于牛轧糖(7.0),因为: 用户添加的CA
    保护所有应用程序数据是 Android应用程序沙箱。Android牛轧糖改变了应用程序的运行方式 与用户和管理员提供的CA交互。默认情况下,应用程序 除非应用程序 显式选择。默认情况下,此安全设置会减少应用程序 攻击表面并鼓励一致处理网络和 基于文件的应用程序数据


  • 对于Android设备,请转到项目根文件夹并运行以下命令:

    adb reverse tcp:[your_own_server_port] tcp:[your_own_server_port]
    
    e、 例如,
    adb反向tcp:8088 tcp:8088

    这将使您的物理设备(即Android手机)在address上侦听在您的开发机器(即您的计算机)上运行的localhost服务器


    之后,您可以在react native
    fetch(
    )调用中直接使用http:localhost:[your_port]/your_api。

    这对我很有效,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用于RESTAPI,我的一个工作案例是替换主机名:
    http://demo.test/api
    机器ip地址:
    http://x.x.x.x/api
    。您可以通过检查无线网络上的ipv4来获取IP。您还应该打开手机的wifi。

    我在Android上也遇到了同样的问题,但是我设法找到了解决方案。默认情况下,Android从API级别28开始阻止明文通信(非https请求)。但是,react-native在调试版本中添加了一个网络安全配置(
    Android/app/src/debug/res/xml/react-native\u-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>
    
    
    本地服务器
    10.0.2.2
    10.0.3.2
    本地开发人员
    
    我在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) 我使用此方法添加了URL的有效证书->步骤2

    http://lpains.net/articles/2018/install-root-ca-in-android/
    
    此证书将添加到“用户”选项卡

    4) 将属性
    android:networkSecurityConfig
    添加到
    <network-security-config>
        <base-config>
            <trust-anchors>
                <certificates src="user"/>
                <certificates src="system"/>
            </trust-anchors>
        </base-config>
    </network-security-config>
    
    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;
    });
    
        <?xml version="1.0" encoding="utf-8"?>
        <manifest ... >
            <application android:networkSecurityConfig="@xml/network_security_config"
                            ... >
                ...
            </application>
        </manifest>
    
    
    <?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>
    
    <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>
    
    headers: {
      Authorization: token,
      'Content-type': 'application/json',
      /** rest of headers... */
    }