当查找键时,allHeaderFields不区分大小写

5
我使用Alamofire来进行API调用。
根据我使用的服务器,响应头可能会大写。
但是根据文档中对于allHeaderFields的描述:
“var allHeaderFields: [AnyHashable : Any] { get }”是一个包含所有HTTP头字段的字典,这些字段作为服务器响应的一部分接收。通过检查该字典,客户端可以看到HTTP服务器返回的“原始”头信息。
字典中的键是从服务器接收到的头字段名称。有关常用HTTP头字段的列表,请参阅RFC 2616。
HTTP标头不区分大小写。为了简化代码,某些标题字段名称被规范化为它们的标准形式。例如,如果服务器发送内容长度标题,则自动调整为Content-Length。
在设置操作期间,返回的标题字典配置为保留大小写(除非具有不同大小写的键已存在),并在查找键时不区分大小写。例如,如果您设置标题X-foo,然后稍后设置标题X-Foo,则字典的键将是X-foo,但值将取自X-Foo标题。
但是,在我的代码中,如果我做这个:
if let headers = response.response?.allHeaderFields {
   print("Access-Token: \(response.response?.allHeaderFields["Access-Token"])")
   print("access-token: \(response.response?.allHeaderFields["access-token"])")
   print("access-token: \(response.response?.allHeaderFields["Access-token"])")
}

在控制台中,我有以下内容:
Access-Token: nil
access-token: Optional(jdRtDzKHNs_i-jt3Lh3a3A)
access-token: nil

我有所不知吗?
3个回答

4
这个错误与Alamofire无关,这是Swift的一个bug。
不幸的是,这是一个已知的bug,在Swift 3转换头文件为Dictionary时出现。自2016年以来,该bug被记录下来并未得到解决。更糟糕的是,他们甚至没有纠正Swift文档。
这违反了HTTP规范,我不知道为什么他们只将其标记为中等优先级。看起来他们不在乎,并且永远不会解决这个问题。
Stephen Gurnett制作了一个解决方法。
Bug报告

感谢您的回答,并指出这非常不幸。确实如此。 截至Swift 4.2,它尚未得到修复。 - CouchDeveloper

1

苹果公司最终提供了一种在Swift中执行不区分大小写的HTTP标头查找的方法。我们应该调用:

HTTPURLResponse.value(forHTTPHeaderField:)

相比使用allHeaderFields,您可以在这里找到此信息(这是Eduardo Vital在他的答案中提供的错误报告链接)。


1

以下扩展适用于所有情况。使用NSDictionary将避免转换为Swift字典,并保持不区分大小写的字典。

extension HTTPURLResponse {
    /// get value for caseless header field
    public final func headerString(field: String) -> String? {
        return (self.allHeaderFields as NSDictionary)[field] as? String
    }
}

有趣的是,在使用可选类型时,这种无需强制转换的特性会消失。
所以以下所有内容都有效:
(self.allHeaderFields as NSDictionary)["Access-Token"]
(self.allHeaderFields as NSDictionary)["access-token"]
(self.allHeaderFields as NSDictionary)["aCCESS-toKEN"]

但以下内容并不起作用:
(self.allHeaderFields as? NSDictionary)?["aCCESS-toKEN"]

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