据我了解的规格,RFC 2616(HTTP/1.1)中引入的ETag是Last-Modified-Header的后继产品,它可以让软件架构师更好地控制它.缓存重新验证过程.
如果存在Cache-Validation-Headers(If-None-Match和If-Modified-Since),则根据RFC 2616,客户端(即浏览器)在检查资源时是否应使用ETag.根据RFC 2616的第14.26节,如果If-None-Match-Header中出现的ETag已更改,则服务器不得以304 Not Modified响应,并且服务器必须忽略其他If-Modified-Since-Header ,如果有的话.如果呈现的ETag匹配,则他不得执行请求,除非Last-Modified-Header中的Date表示如此.(如果提供的ETag匹配,服务器应该在GET或HEAD请求的情况下响应304 Not Modified ...)
这部分为一些猜测留下了空间:
...好的当我写这篇文章的时候,问题就是这个答案:
上面提到的(小)矛盾是因为弱ETag.标有弱ETag的资源可能已经改变,尽管ETag没有.因此,在弱ETag的情况下,当ETag没有改变时回答304 Not Modified是错误的,但是If-Modified-Since中呈现的日期不匹配,对吧?
我正在尝试向我的REST API发出请求,我对Firefox没有任何问题,但在Chrome中我无法让浏览器工作,总是抛出200 OK
,因为没有if-none-match
(或类似的)标头被发送到服务器.
使用Firefox我304
完美无缺.
我想我错过了一些东西,我试着Cache-Control: max-age=10
测试但没有.
是否有一个Ruby http客户端库,其中响应由ETag自动缓存,If-Non-Match标头应用于以前使用的URL上的请求?
是否NSURLCache
透明地处理服务器收到的ETag?
我的意思是:它是否自动存储每个URL请求的ETag,然后在If-None-Match
提交相同URL的请求时发送适当的?或者我必须自己管理它?
ETag 标头的定义 ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag ):
ETag HTTP 响应标头是资源特定版本的标识符。它使缓存更加高效,并节省带宽,因为如果内容未更改,Web 服务器不需要发送完整响应。另一方面,如果内容发生更改,etag 有助于防止资源的同时更新相互覆盖(“空中冲突”)。
Cache-Control 标头的定义 ( https://developer.mozilla.org/de/docs/Web/HTTP/Headers/Cache-Control ):
Cache-Control 通用标头字段用于指定请求和响应中的缓存机制的指令。
因此,ETag 标头告诉资源浏览器向服务器发送单个 HTTP 请求,并询问文件哈希是否已更改。如果是,请下载一个新的。伟大的。那么,如果设置了 ETag 标头,为什么我还需要 Cache-Control(除了 Expires 标头,这可能有助于避免这个单一请求)?
因此,如果我必须设置 Cache-Control 标头,它只会有害,对吧?我认为最合适的值是:
Cache-Control: must-revalidate
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否会引发不必要的额外操作。
我理解使用etags进行乐观并发控制(例如在RESTful风格的体系结构中),并且我已经读过etags对于同一资源的不同表示应该是不同的.这是为什么?
最终,我们是否有兴趣了解资源是否已更改,以便我们可以处理并发修改?我甚至很难想象资源的表示会在没有资源本身变化的情况下发生变化,所以我显然缺少一些基本的理解.
在RESTful接口中处理乐观锁定的推荐方法似乎是ETag
从GET 返回一个并If-Match
在PUT上提供一个,即:
GET /items/1 --> gives client an ETag for a single item
PUT /items/1 <-- client gives it back as If-Match for checking
Run Code Online (Sandbox Code Playgroud)
如何将此方案与多个项目一起使用,例如,如果我要批量从单个URI中获取多个项目:
GET /items --> How do I return multiple ETags for multiple items here?
Run Code Online (Sandbox Code Playgroud)
或者,如果ETags/If-Match不能应对这种情况,那么推荐的方法是什么?或者我应该自己动手?
是否有关于如何向Retrofit + OkHttp 添加缓存和ETAG
/ If-None-Match
支持的正确解释?我正在努力为Etag
2个项目添加支持,起初我怀疑HTTP标头可能存在问题,另一个项目已正确设置,缓存仍无法按预期工作.
以下是我试图让它发挥作用.结果显示缓存似乎在应用程序的同一个实例中工作,但是一旦我重新启动 - 所有内容都会再次加载.此外,在我的日志中,我没有看到If-None-Match
被添加到请求中,因此我假设服务器不知道ETag
并且仍然完全重新计算响应.
以下是一些代码示例:
public class RetrofitHttpClient extends UrlConnectionClient
{
private OkUrlFactory generateDefaultOkUrlFactory()
{
OkHttpClient client = new com.squareup.okhttp.OkHttpClient();
try
{
Cache responseCache = new Cache(baseContext.getCacheDir(), SIZE_OF_CACHE);
client.setCache(responseCache);
}
catch (Exception e)
{
Logger.log(this, e, "Unable to set http cache");
}
client.setConnectTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS);
client.setReadTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS);
return new OkUrlFactory(client);
}
private final OkUrlFactory factory;
public RetrofitHttpClient()
{
factory = generateDefaultOkUrlFactory();
}
@Override
protected HttpURLConnection openConnection(retrofit.client.Request request) throws …
Run Code Online (Sandbox Code Playgroud) 即使我发送"缓存控制:必须重新验证",Google Chrome在浏览器中使用来回按钮时也会使用本地缓存页面.
这是原始回复的一部分:
HTTP/1.1 200 OK
cache-control: private, must-revalidate
etag: "c9239b5d4b98949f8469a05062e05bb999d7512e"
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Run Code Online (Sandbox Code Playgroud)
如果我刷新页面,我得到一个"HTTP/1.1 304 Not Modified"响应但是当我使用后退按钮时,我得到以下响应:
Request URL:example.com
Request Method:GET
Status Code:200 OK (from cache)
Run Code Online (Sandbox Code Playgroud)
我正在寻找的响应是304或200 OK,是否有可能实现这一目标?