无法在 React Native 中获取或向 http URL 发出 XHR 请求(但 https 和 http://localhost 工作正常)

Posted

技术标签:

【中文标题】无法在 React Native 中获取或向 http URL 发出 XHR 请求(但 https 和 http://localhost 工作正常)【英文标题】:Can't fetch or make XHR request to http URL in React Native (but https and http://localhost work fine) 【发布时间】:2018-01-03 05:14:12 【问题描述】:

我尝试在 React Native 中向远程服务器发出请求,但总是得到TypeError: Network request failed;我尝试了不同的URL,发现如果我向http://rap2api.taobao.org/app/mock/3008/GET/api/creations这样的http URL发出请求,它总是失败; 如果我向 https://facebook.github.io/react-native/movies.json 之类的 https URL 发出请求,它会起作用; 如果我向http://localhost:3002/list 之类的 http localhost URL 发出请求,它也可以工作。

componentDidMount() 
  console.log("_fetchData");
  this._fetchData()

_fetchData = () => 
      fetch('http://rap2api.taobao.org/app/mock/3008/GET/api/creations')
        .then((response) => response.json())
        .then((responseJson) => 
          console.log('responseJson',responseJson)
        )
        .catch((error) => 
          console.error(error);
        );
    

我在网上查了很多参考资料,猜想这与 Info.plist doc 中的设置有关。我试着做一些修改,比如:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>localhost</key>
    <dict>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
    <key>rap2api.taobao.org</key>
    <dict>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <key>NSIncludesSubdomains</key>
      <true/>
    </dict>
  </dict>
</dict>

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

但是,它们都不起作用,我在请求 http URL 时仍然遇到同样的错误。我确信 API 很好,因为我在 Web 应用程序上尝试过它并成功获得响应。有什么问题?

【问题讨论】:

【参考方案1】:

来自https://facebook.github.io/react-native/docs/network.html

默认情况下,ios 会阻止任何未使用 SSL 加密的请求。如果您需要从明文 URL(以 http 开头的 URL)获取,您首先需要添加应用程序传输安全异常。如果您提前知道需要访问哪些域,则仅为这些域添加例外会更安全;如果直到运行时域才知道,您可以完全禁用 ATS。但请注意,从 2017 年 1 月起,Apple 的 App Store 审核将需要合理的理由来禁用 ATS。有关详细信息,请参阅 Apple 的文档。

来自https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

从 iOS 10.0 及更高版本以及 macOS 10.12 及更高版本开始,支持以下子项: NSAllowsArbitraryLoadsForMedia NSAllowsArbitraryLoadsInWebContent NSRequiresCertificateTransparency NSAllowsLocalNetworking注意:有两个“允许任意加载”键,它们采用不同的命名模式。注意正确使用…ForMedia 和…InWebContent。

您可以尝试明确设置 NSAllowsArbitraryLoadsForMedia 和 NSAllowsArbitraryLoadsInWebContent。

还要确保在 Xcode 中清理和重建您的项目,以便更新后的 plist 设置包含在您的包中。

【讨论】:

您好,感谢您的回答。我尝试设置 NSAllowsArbitraryLoadsForMedia 和 NSAllowsArbitraryLoadsInWebContent,但仍然没有解决错误。我认为您的回答是正确的,但我猜 info.plist 可能不会生效。我不知道如何在 react native 中“清理并重建你的项目在 Xcode 中”,我试图在 Xcode 中打开 react native 项目的 ios 文件夹,然后单击构建按钮,但它导致错误。我没有任何 ios 开发经验,只是开始学习 react native。你能给出重建我的 react native 项目的任何想法吗? 在产品菜单中查找清理和构建。如果您使用“播放”按钮(三角形),除非您在右侧指定设备,否则会出现错误 - “通用 iOS 设备”是默认设置,不能用于运行。您可以选择模拟器或 USB 连接的物理设备。无论如何,即使这不能解决问题,也许上面文档的链接会有所帮助。 终于成功了。解决该错误的最终设置是使用 NSExceptionDomains,我在 Xcode 中重建它,然后它成功获取 API。谢谢。

以上是关于无法在 React Native 中获取或向 http URL 发出 XHR 请求(但 https 和 http://localhost 工作正常)的主要内容,如果未能解决你的问题,请参考以下文章

无法在 React-native 中使用 127.0.0.1 从获取请求中获取响应

React Native Agora 无法在我的项目频道中获取流列表

用户拒绝激活位置时无法获取 - React Native Geolocation Service

在没有 GPS 的情况下,使用 navigator.geolocation 在 react-native 上无法获取当前位置

无法使用 this.state.data.map() 在 react native firebase 中显示获取的数据

在 React Native 中获取广告 id