查找钥匙时,Allheaderfields并不是不敏感的



我正在使用Alamofire进行API调用。

根据服务器,我正在使用的响应标头可能会大写。

但是,正如文档所说的Allheaderfields:

var allheaderfields:[Anyhashable:any] {get}

作为服务器响应的一部分收到的所有HTTP标头字段的字典。通过检查该字典客户端可以看到HTTP服务器返回的" RAW"标头信息。

该字典中的键是从服务器接收的标题字段名称。有关常用的HTTP标头字段列表,请参见RFC 2616。

HTTP标头不敏感。为了简化您的代码,某些标头字段名称被典型地化为其标准形式。例如,如果服务器发送内容长度的标头,则将自动调整为内容长度。

返回的标题词典配置为在设定操作期间具有案例保护(除非键已经存在不同的情况(,并且在查找键时对案例不敏感。

例如,如果您设置了标题X-foo,然后将标题X-foo设置为X-foo,则字典的键将是X-foo,但值将取自X-Foo Header。

但是,如果我这样做的话,请在我的代码中:

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

我想念什么吗?

该错误与Alamofire无关。这是一个迅速的错误。

不幸的是,这是一个已知的错误,当他们将标题转换为字典时出现在Swift 3。该错误自2016年以来一直注册,但仍未解决。为了使事情最糟糕,他们甚至没有纠正迅速的文档。

这是对HTTP规范的违反,我不知道为什么他们仅将其标记为中等优先级。似乎他们不在乎,永远不会解决这个问题。

Stephen Gurnett进行了解决方法

错误报告

Apple最终提供了一种为Swift中的HTTP标头做细心的查找的方法。我们应该致电:

HTTPURLResponse.value(forHTTPHeaderField:)

而不是使用allHeaderFields。您可以在此处找到此信息(这是Eduardo Cital提供的错误报告链接(。

扩展程序以下适合所有条件。由于nsdictionary将避免转换为SWFIT词典,并保持案例不敏感的词典。

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"]

最新更新