我得到“Error Domain=NSURLErrorDomain Code=-1001“请求超时”。在iOS设备上但在android上工作正常

odd*_*odd 6 node.js ios swift server

服务器:带有 nodejs express 和 nginx 代理的 Ubunta。

使用我的 android 应用程序时一切正常。

使用我的 iOS 应用程序时,我得到:

“错误调用 GET on /district Error Domain=NSURLErrorDomain Code=-1001 “请求超时。” UserInfo={NSUnderlyingError=0x1c0458db0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 “(null)” UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey= http://xxx.xxx.xxx.xxx/api/district , NSErrorFailingURLKey= http://xxx.xxx.xxx.xxx/api/district , _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102 , NSLocalizedDescription=请求超时。}"

此错误仅在我执行 GET 请求时发生。我可以登录(POST)并将标记添加到我的地图等。一切正常。但是通过 get 请求获取数据不是。

我认为问题与 iOS 有 30 秒超时/在 iOS 6 或 7 上的设备上保持活动状态有关。它会自动设置一个标头以保持活动状态 30 秒。

在我的 mac localhost 服务器上工作时,我遇到了类似的问题。但是我通过用 res.set("Connection", "close"); 发回一个标头来修复它。在我的 nodejs 路由回 iOS。像这样:

nodejs DistrictRoutes.js

router.get('/api/district', passport.authenticate('jwt', { session:false }), function(req, res, next) {
  log.info("inside getting districts");
  District.find({}, function(err, district) {
    if (err){
      res.set("Connection", "close");
      log.info("error getting districts");
      res.status(404).json({message:"no districts found" + err});
      res.end();
    }else{
      res.set("Connection", "close");
      log.info("success getting districts");
      res.json(district);
      res.end();
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

快速的iOS应用程序。在 httpRequester 帮助器类中

func getRequest (urlPath: String, body: [String:String], success:  @escaping (Data, HTTPURLResponse) -> ()) {
    let token: String! = KeychainWrapper.standard.string(forKey: "token")

    //check if url is a proper URL string
    guard let url = URL(string: baseUrl+urlPath) else {
        print("Error: cannot create URL")
        return
    }

    var urlRequest = URLRequest(url: url)
    urlRequest.httpMethod = "GET"
    urlRequest.addValue("JWT " + token, forHTTPHeaderField: "Authorization")
            //urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
            //urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")

    let jsonData: Data
    do {
        jsonData = try JSONSerialization.data(withJSONObject: body)
        urlRequest.httpBody = jsonData
    } catch {
        print("Error: cannot create JSON from body")
        return
    }
    let task = URLSession.shared.dataTask(with: urlRequest) { (data: Data?, response: URLResponse?, error: Error?) in
        guard error == nil else {
            if let httpResponse = response as? HTTPURLResponse {
                self.errorHandling(response: httpResponse)
            }
            print("error calling GET on /" + urlPath)
            print(error!)
            return
        }
        guard let responseData = data else {
            print("Error: did not receive any data")
            return
        }
        let httpResponse = response as! HTTPURLResponse
        success(responseData, httpResponse)
    }

    task.resume()
}
Run Code Online (Sandbox Code Playgroud)

我在当前的 ubunta 服务器上有相同的代码,如上所述,android 工作正常。在 iOS 上发布请求也是如此,但不是 GET 请求。问题出现在 iOS 设备上的展位 wifi 和 4g 连接上。

如果您需要我提供任何其他帮助来帮助解决此问题,请告诉我。

谢谢!

odd*_*odd 1

解决方案是不使用 GET 请求发送正文。我知道它不遵循 GET 的请求模式。认为这是可能的。

就我而言,这是一个糟糕的项目计划。我作为开发人员的第一个项目之一。所有非秘密的识别信息都应保存在令牌内。因此,当发送 get 请求时,带有令牌的标头包含过滤发送回用户的数据所需的所有信息。

祝你好运,希望有帮助!