【问题标题】:Swift 5 NSURLComponents Query String %3FSwift 5 NSURLComponents 查询字符串 %3F
【发布时间】:2021-02-13 01:42:39
【问题描述】:

我正在从远程服务器获取 json。

当我构建 url 时,查询字符串是 ?,但是,当它通过数据任务发送时,?被编码为 %3F,我的调用失败了。

如何防止 urlComponents 对查询字符串进行编码?我已经切换了实际值。

//Note: the host and path are coming from info.plist, I just added them in here.
 string host = servicehost.com 
 string path = "/service/getData?cc=al&lastDate="

 let urlComponents = NSURLComponents.init()
 urlComponents.scheme = "https"
 urlComponents.host = host
 urlComponents.path = path

当我打印出值时:,我得到

print(": urlComponents.url! \(urlComponents.url!)")
https://servicehost.com/service/getData%3Fcc=al&lastDate=

在dataTask内部,检查时出现以下错误:

Printing description of error:
▿ DecodingError
  ▿ typeMismatch : 2 elements
    - .0 : Swift.String
    ▿ .1 : Context
      ▿ codingPath : 3 elements
        - 0 : CodingKeys(stringValue: "data", intValue: nil)
        - 1 : CodingKeys(stringValue: "date-published", intValue: nil)
        - 2 : CodingKeys(stringValue: "date", intValue: nil)
      - debugDescription : "Expected to decode String but found a number instead."
      - underlyingError : nil
Printing description of data:
▿ 0 bytes
  - count : 0
  ▿ pointer : 0x00007f90d2fdd000
    - pointerValue : 140259991867392
  - bytes : 0 elements

数据大小为: jsonDecodableTask: 68 bytes

失败信息是:

Failure: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))

如果我进入浏览器并输入带有编码查询字符串的 url,我会返回以下内容: <html><head><title>Error</title></head><body>Not Found</body></html>

如果我转到浏览器并将 %3F 更改为 ?,则请求成功。

【问题讨论】:

  • 这里棘手的部分是 URL 的不同部分需要不同的转义规则。您的 URL 的路径不应包含“?”人物。这 ”?”表示查询参数部分的开始。 (您的 URL 的整个 ?cc=al&lastDate= 部分不应该在路径中。)请参阅 Leo 的答案以了解如何正确构建您的 URL。

标签: json swift url encoding


【解决方案1】:

问题在于"?" 不是路径的一部分。它应该在您添加 URL 的查询项组件时自动添加:

let host = "www.google.com"
let path = "/service/getData"
let queryItems: [URLQueryItem] = [.init(name: "cc", value: "al"),
                                  .init(name: "lastDate", value: "")]
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems =  queryItems
urlComponents.url?.absoluteString  // "https://www.google.com/service/getData?cc=al&lastDate="

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-05
    • 2022-01-10
    • 2021-09-07
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    相关资源
    最近更新 更多