ETag和If-None-Match HTTP头部不起作用。

16

我有一个文件在我的 Web服务器 上,每次访问时都会从服务器下载它,因为文件内容可能已更改。但如果文件已更改,我希望只在那个时间下载,以节省带宽,这就是 ETagIf-None-Match 的作用。

  • 第一次请求时,我会从HTTP响应标头中检索 ETag 值。

首次请求文件

  • 在后续请求中下载该文件时,我会将 Etag 值附加到 If-None-Match 标头字段中,以便如果没有更改,则会收到 HTTP 响应状态码 304,否则会收到 200。

    对同一文件的第二次请求

注意:

当我尝试在 Chrome 中的 Advanced REST Client 应用程序中执行上述步骤时,它可以正常工作,但是当我尝试在 iOS 中执行时,我总是得到响应代码 200,但应该给我 304。

下面是我使用的示例代码

var request1 =  NSMutableURLRequest(URL:NSURL(string: "http://10.12.1.101/Etag/ringtone1.mp3")!)
let Etagvalue="\"36170-52c1cc36d9b40\""
var session1 = NSURLSession.sharedSession()
request1.HTTPMethod = "GET"
var err: NSError?
request1.addValue(Etagvalue, forHTTPHeaderField: "If-None-Match")

var task = session1.dataTaskWithRequest(request1, completionHandler: {data, response, error -> Void in
       print("response: \(response)")

})

这是回应内容

回应: 可选的( { URL: http://10.12.1.101/Etag/ringtone1.mp3 } { 状态码: 200, 头部 { "Accept-Ranges" = bytes; Connection = "Keep-Alive"; "Content-Length" = 221552; "Content-Type" = "audio/mpeg"; Date = "Wed, 24 Feb 2016 14:57:53 GMT"; Etag = "\"36170-52c1cc36d9b40\""; "Keep-Alive" = "timeout=5, max=100"; "Last-Modified" = "Fri, 19 Feb 2016 10:15:33 GMT"; Server = "Apache/2.4.16 (Unix) PHP/5.5.29"; } })

我在这里做错了什么?


1
展示我们生成的请求。例如,使用代理服务器(例如Charles)。 - Daij-Djan
@Daij-Djan - 除了服务器端配置,E-tag是否还有其他的依赖关系?我的手指仍然交叉着,它是如何开始工作的? - Durai Amuthan.H
不这样想...嗯,你得不在本地存现金,但我觉得你没有;) -- 所以不行 :/ - Daij-Djan
@Daij-Djan - 我在请求中没有指定任何缓存策略,因此默认的NSURLRequestCachePolicy.UseProtocolCachePolicy将是行为...所以会发生缓存。 - Durai Amuthan.H
@Daij-Djan - 我可以安全地假设在请求中禁用缓存可以解决不一致性问题吗? - Durai Amuthan.H
显示剩余3条评论
4个回答

19

我遇到同样的问题。我发现这是由于cachePolicy引起的。你需要将它设置如下:

request.cachePolicy = .ReloadIgnoringLocalAndRemoteCacheData

你会没事的。


这应该被标记为答案。很棒的发现! - Konstantin Loginov
1
这对我有用。你能把它标记为解决方案吗? - Naknut
这让我省了好几个小时的追踪,为什么S3忽略了我的If-None-Match头部信息,谢谢!!! - Samah
真的花了两个星期找到这个。谢谢!! - Liam Bolling

2

CachePolicy 命名规则很令人困惑,更好的做法是它实际上并没有实现其中一些...

这篇文章很好地解释了它们。 http://nshipster.com/nsurlcache/

此外,如果您让 Cache Policy 使用 UseProtocolCachePolicy,那么您的 NSURLSession 将接收到状态码为 200 的响应,该响应是由缓存生成的。


0
该问题是由缓存策略'useProtocolCachePolicy'、'returnCacheDataElseLoad'或'returnCacheDataDontLoad'引起的。
您可以使用以上任何其他策略。最好使用‘reloadIgnoringLocalAndRemoteCacheData’。

0
最近引入了.reloadRevalidatingCacheData,听起来比老式的reloadIgnoringLocalAndRemoteCacheData方式更有效率。

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