React Native iOS模拟器网络连接问题

4
我正在尝试在我的react-native应用程序中获取数据,但是失败了。因此,我找到了NetInfo并在每个MapView的onRegionChangeComplete事件和应用程序启动时使用它(如果有影响的话,是iPhone5s和iPhone 6),而NetInfo返回的状态每次都是未知。MapView工作正常,我可以使用模拟器上的Safari浏览网页。我发现与fetch()失败相关的最常见问题来自于开发人员在其url中使用localhost。我正在使用http://api.openweathermap.org/data/2.5/weather?作为我的url,所以我相信这是一个模拟器问题。我没有iOS设备进行测试,并且MapView尚不可用于Android,因此我无法在Android上进行测试。请问有人能指点我正确的方向吗?
谢谢。
PS. 我在控制台记录的fetch错误是- TypeError: Network request failed 以下是我的代码:
module.exports = function(latitude, longitude) {


  var rootURL = 'http://api.openweathermap.org/data/2.5/weather?APPID=MYAPIKEY&lat=35&lon=139';
  console.log(rootURL);

  return fetch(rootURL) // fetch is part of react or react-native, no need to import
    .then(function(response){ // method chaining used here
      // Shorthand to check for an HTTP 2xx response status.
      // See https://fetch.spec.whatwg.org/#dom-response-ok
      if (response.ok) {
        console.log('Response from fetch was ok, returning response to next then');
        return response
      } else {
      // Raise an exception to reject the promise and trigger the outer .catch() handler.
      // By default, an error response status (4xx, 5xx) does NOT cause the promise to reject!
      console.log('Throwing error to .catch with statusText: ' + response.statusText);
      throw Error(response.statusText);
    }

    })
    .then(function(response) {
      console.log('Returning JSON to next then')
      return response.json();
    })
    .then(function(json) { // chain a second function when JSON is returned
      console.log('Returning this json to Api call in index.os.js' + json);
      return {
        city: json.name,
        //temperature: kelvinToF(json.main.temp),
        //decription: json.weather[0].description
      }
    })
    .catch(function (error) {
      console.log('My fetch Error: ' + error + 'Specific error: ' + error.message);
    })
}

第二次更新:除了下面的更新和信息之外,我已经确定这是一个iOS模拟器问题。在Android设备上没有同样的问题。再次强调 - 模拟器出现问题的唯一时间是使用http: url进行fetch()请求。当我使用https: url时,模拟器很快乐。我还在模拟器中找到了一些DEV设置,允许http请求。但是这对我没有任何影响。

更新:我将问题缩小到url。如果我在react-native中使用此url进行fetch,url为http://api.openweathermap.org/data/2.5/weather?APPID=MYAPPKEY&lat=35&lon=139,其中MYAPPKEY等于我的密钥,它会失败。如果我在浏览器中使用相同的url,它会返回我期望的json。

另外,如果我在react-native中使用fetch并使用此url https://api.github.com/users/mralexgray/repos,我不会得到“Network request failed”,而是得到有效的json。

还有一个有趣的注释 - 如果我在浏览器中输入openweathermap url,当它返回json时,地址栏会去掉http://部分。当我在浏览器中输入github地址时,地址栏保留https://。

另一个有趣的注释 - 如果我使用非https url,它会失败。


你应该提供至少一些代码 - itinance
我不认为这是代码问题。我已经在“更新”下更新了我的问题。 - MrDMAdev
1
可能是因为iOS ATS机制,尝试禁用它。https://dev59.com/o10Z5IYBdhLWcg3wnBb_ - Xeijp
谢谢。那是正确的答案!如果您想要更多的信誉,可以自由地将其作为官方答案! - MrDMAdev
1个回答

9
如果你正在使用 react-native@0.28 或更高版本,那么在 Plist.Info 中将删除以下内容:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>

并且添加了以下内容:

<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSAppTransportSecurity</key>
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

这涉及到iOS中的ATS,更多信息请查看以下链接。你需要将使用的http域名添加到plist.Info中。 https://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

谢谢您提供的额外信息和答案。我在另一个讨论中看到,苹果将在年底彻底取消这个功能。不给我们提供不需要使用凭据的简单API获取数据的选项有点愚蠢。 - MrDMAdev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接