iOS设备GET请求超时(NSURLErrorDomain Code=-1001)求助
解决iOS GET请求超时(Error Domain=NSURLErrorDomain Code=-1001)的问题
我之前碰到过类似的跨端请求超时问题,咱们一步步拆解排查:
1. iOS端GET请求带HTTP Body是核心隐患!
看你的Swift代码,GET请求居然设置了httpBody——虽然HTTP规范没有完全禁止GET带body,但绝大多数HTTP客户端、服务器(包括Nginx)对这种场景的处理逻辑不一致,这大概率是iOS请求超时的元凶。
GET请求的参数应该放在URL的Query String里,而非请求体中。修改你的Swift代码:
func getRequest (urlPath: String, queryParams: [String:String], success: @escaping (Data, HTTPURLResponse) -> ()) { let token: String! = KeychainWrapper.standard.string(forKey: "token") // 把参数拼接成Query String var components = URLComponents(string: baseUrl+urlPath)! components.queryItems = queryParams.map { URLQueryItem(name: $0.key, value: $0.value) } guard let url = components.url else { print("Error: cannot create URL") return } var urlRequest = URLRequest(url: url) urlRequest.httpMethod = "GET" urlRequest.addValue("JWT " + token, forHTTPHeaderField: "Authorization") // 移除所有和httpBody相关的代码! let task = URLSession.shared.dataTask(with: urlRequest) { (data: Data?, response: URLResponse?, error: Error?) in // 后续逻辑不变... } task.resume() }
2. 修正Nginx反向代理的长连接配置
之前本地用Connection:close有用,但服务器端无效,大概率是Nginx的代理配置没正确处理HTTP连接头。修改你的Nginx配置(在对应location块内):
location /api/ { proxy_pass http://localhost:3000; # 替换成你的Node.js服务地址 proxy_http_version 1.1; # 强制使用HTTP/1.1,适配长连接逻辑 proxy_set_header Connection ""; # 让Nginx自动处理连接头,覆盖客户端的Connection设置 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 调整超时参数,避免Nginx提前断开连接 proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; keepalive_timeout 65; }
修改后重启Nginx:sudo systemctl restart nginx
3. 修复Node.js端的响应冗余问题
你的Node.js代码中,res.json()之后又调用了res.end()——但res.json()方法已经自动完成了响应序列化、发送和结束操作,额外调用res.end()会导致响应异常(比如重复关闭连接),客户端可能无法完整接收响应而超时。
修改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"); 和 res.end(); log.info("error getting districts"); res.status(404).json({message:"no districts found" + err}); }else{ // 移除res.set("Connection", "close"); 和 res.end(); log.info("success getting districts"); res.json(district); } }); });
4. 额外排查点
- 验证JWT认证流程:在服务器端添加更多日志,比如在
passport.authenticate之后立刻打印日志,确认请求是否成功通过认证并进入业务逻辑。如果认证环节卡住,也会导致超时。 - 测试无认证的GET请求:临时注释掉
passport.authenticate,直接返回数据,看iOS端是否能正常接收,排除认证模块的问题。 - 检查服务器防火墙/安全组:确保服务器的对应端口(比如80/443)允许iOS设备的IP访问,避免请求被拦截。
先按这几个步骤来,应该能解决超时问题。如果还有问题,可以把Nginx的access.log和error.log相关片段、或者Node.js的日志细节贴出来,咱们再进一步排查。
内容的提问来源于stack exchange,提问作者odd
相关产品推荐
相关产品推荐

