状态代码400:使用URLSession.shared.dataTask进行的调用的NSHTTPURLResponse

时间:2017-06-22 17:51:49

标签: ios11 xcode9-beta swift4 urlsession

这是我在将iOS 11(15A5304i)和Xcode 9(9M137d)更新到最新测试版后开始的问题。

当我恢复到以前的测试版时,它会消失。

对网站进行任何GET https调用都会导致服务器发出400响应。

func callTask(_ request: URLRequest, completion: @escaping (ResultType<Data, NetworkError>) -> Void) {
  let task = URLSession.shared.dataTask(with: request) { data, response, error in

    guard let response = response as? HTTPURLResponse else {
      completion(.failure(.responseInvalidFormat))
      return
    }

    if response.statusCode >= 400 {
      let error = response.description
      completion(.failure(.responseStatusError(status: response.statusCode, message: error)))
      return
    }

    guard let data = data else {
      completion(.failure(.responseNoDataError))
      return
    }

    completion(.success(data))
  }
  task.resume()
}

这就是我打电话的方式

  private func generateRequest(urlString: String,
                               method: HttpMethod = .get,
                               contentType: ContentType = .json,
                               headers: [String: String] = ["":""],
                               body: [String: Any]? = nil) throws -> URLRequest {


    guard let url = URL(string: urlString) else {
      throw NetworkError.requestGenerationFail(url: urlString, httpMethod: method)
    }
    var request = URLRequest(url: url)
    request.httpMethod = method.rawValue
    request.setValue("***** by Reza: info: reza@example.com", forHTTPHeaderField: "User-Agent")

    request.allHTTPHeaderFields = headers
    if contentType == .urlEncoded && headers["content-type"] ?? "" != ContentType.urlEncoded.rawValue {
      request.addValue(ContentType.urlEncoded.rawValue, forHTTPHeaderField: "content-type")
    }

    if let body = body {
      request.httpBody = try self.generateBody(body: body, contentType: contentType)
    }

    return request
  }

这就是请求的生成方式:

class MyClass

同样,这在之前的iOS 11测试版中运行良好,但新版本会对https调用Web服务器产生400响应,几乎没有数据。

值得注意的是,我首先打电话给https://api.yelp.com/托管的Yelp端点API。此连接成功,没有任何问题。对其他主持人(https://stackoverflow.comhttps://www.yelp.com)的任何进一步调用都会返回400.

当我使用旧测试版在模拟器中运行代码时,它运行正常,当我部署到使用新iOS的iPhone 6时,它会从服务器产生400。

我还没有针对我拥有的服务器对此进行测试,因此我可以查看日志,但是一路走来正在打破并导致服务器因错误的请求响应而重新出现。使用curl,postman,浏览器和之前的iOS版本,这些调用工作正常。

我希望有人遇到同样的问题可以解释一下。

1 个答案:

答案 0 :(得分:1)

我已经明确了这个问题。虽然原因仍然难以捉摸。

generateRequest函数中,我为请求标头传递了[String:String]字典,默认值为["":""]

request.allHTTPHeaderFields = ["":""]似乎会破坏您的请求。

在之前的版本中,这不会导致任何问题,但这会导致对当前测试版的错误请求。

<强>更新

当我第一次遇到这个问题时,我填写了一个关于Apple的错误,这是他们的答案:

问题在于CFNetwork-856.4.7(种子1的一部分)我们犯了一个错误并删除了空白的标题。在种子2中,(CFNetwork-861.1)我们将要删除的标题限制为4个“特殊”标题(Content-Type,User-Agent,Accept-Language,Accept-Encoding)。所以,这就是你看到行为改变的原因。

macOS El Capitan还发送导致400 HTTP状态代码的“=”标头。因此,现在种子2中的表现正确。种子1是异常的并且错了。

请通过更新您的错误报告告诉我们您是否已解决此问题。