简体   繁体   English

如何使任意 URL 的缓存失效?

[英]How to invalidate the cache of an arbitrary URL?

According tohttp://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10 clients must invalidate the cache associated with a URL after a POST, PUT, or DELETE request.根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10 ,客户端必须在 POST、PUT 或 DELETE 请求后使与 URL 关联的缓存无效。

Is it possible to instruct a web browser to invalidate the cache of an arbitrary URL, without making an HTTP request to it?是否可以指示 web 浏览器使任意 URL 的缓存无效,而不向其发出 HTTP 请求?

For example:例如:

  1. PUT /companies/Nintendo creates a new company called "Nintendo" PUT /companies/Nintendo创建一个名为“Nintendo”的新公司
  2. GET /companies lists all companies GET /companies列出所有公司
  3. Every time I create a new company, I want to invalidate the cache associated with GET /companies .每次创建新公司时,我都想使与GET /companies关联的缓存无效。 The browser doesn't do this automatically because the two operate on different URLs.浏览器不会自动执行此操作,因为两者在不同的 URL 上运行。

Is the Cache-Control mechanism inappropriate for this situation? Cache-Control机制是否不适合这种情况? Should I use no-cache along with ETag instead?我应该将no-cacheETag一起使用吗? What is the best-practice for this situation?这种情况的最佳做法是什么?

I know I can pass no-cache the next time I GET /companies but that requires the application to keep track URL invalidation instead of pushing the responsibility to the browser.我知道我可以在下次GET /companies时传递no-cache ,但这需要应用程序跟踪 URL 失效而不是将责任推给浏览器。 Meaning, I want to invalidate the URL after step 1 as opposed to having to persist this information and applying it at step 2. Any ideas?意思是,我想在步骤 1 之后使 URL 无效,而不是必须保留此信息并在步骤 2 应用它。有什么想法吗?

Yes, you can (within the same domain).是的,您可以(在同一域内)。 From this answer (slightly paraphrased):这个答案(稍微释义):

In response to a PUT or POST request, if the Content-Location header URI is different from the request URI, then the cache for the Content-Location URI is invalidated.在响应 PUT 或 POST 请求时,如果 Content-Location header URI 与请求 URI 不同,则 Content-Location URI 的缓存无效。

So in your case, include a Content-Location: /companies header in response to your POST request.因此,在您的情况下,包括Content-Location: /companies header 以响应您的 POST 请求。 This will invalidate the browser's cached version of /companies .这将使浏览器的/companies缓存版本失效。

Note that this does not work for GET requests.请注意,这不适用于 GET 请求。

No, in HTTP/1.1 you may only invalidate a client's cache for a resource in a response to a request for that resource.不,在 HTTP/1.1 中,您只能在响应对该资源的请求时使客户端的资源缓存无效。 It may be in response to a PUT , POST or DELETE rather than a GET (see RFC 7234, section 4.4 for details).它可能响应PUTPOSTDELETE而不是GET (有关详细信息请参阅RFC 7234 第 4.4 节)。

If you have a resource where you need clients to confirm that they have the latest version then no-cache and an entity tag is an ideal solution.如果您的资源需要客户端确认他们拥有最新版本,那么no-cache和实体标签是理想的解决方案。

HTTP/2 allows for pushing a cache clear ( Nine Things to Expect from HTTP/2 4. Cache Pushing ). HTTP/2 允许推送缓存清除( HTTP/2 的九件事4. 缓存推送)。

In the link which you have given "the phrase "invalidate an entity" means that the cache will either remove all instances of that entity from its storage, or will mark these as "invalid" and in need of a mandatory revalidation before they can be returned in response to a subsequent request.".在您提供的“使实体无效”的链接中,缓存将从其存储中删除该实体的所有实例,或者将这些实例标记为“无效”并需要强制重新验证才能被响应后续请求而返回。”。 Now the question is where are the caches?现在的问题是缓存在哪里? I believe the Cache the article is talking about is the server cache.我相信文章所谈论的缓存是服务器缓存。

I have worked on a project in VC++ where whenever a model changes the cache is updated.我曾在 VC++ 中从事过一个项目,每当模型更改时,缓存就会更新。 There is a programming logic implemention involved to achieve this.有一个编程逻辑实现来实现这一点。 Your mentioned article rightly says "There is no way for the HTTP protocol to guarantee that all such cache entries are marked invalid" HTTP Protocol cannot invalidate cache on its own.您提到的文章正确地说“HTTP 协议无法保证所有此类缓存条目都标记为无效” HTTP 协议无法自行使缓存无效。

In our project example we used publish subscribe mechanism.在我们的项目示例中,我们使用了发布订阅机制。 Wheneven an Object of class A is updated/inserted it is published to a bus.当更新/插入 A 类对象时,它也会发布到总线。 The controllers register to listen to objects on the Bus.控制器注册以侦听总线上的对象。 Suppose A Controller is interested in Object A changes, it will not be called back whenever Object Type B is changed and published.假设一个控制器对对象 A 的变化感兴趣,它不会在对象类型 B 发生变化和发布时被回调。 When Object Type A indeed is changed and published then Controller A Listener function updates the Cache with latest changes of Object A. The subsequent request of GET /companies will get the latest from the cache.当对象类型 A 确实被更改并发布时,控制器 A 侦听器函数会使用对象 A 的最新更改更新缓存。 GET /公司的后续请求将从缓存中获取最新信息。 Now there is a time gap between changing the object A and the Cache being refreshed with the latest changes.现在,更改对象 A 和使用最新更改刷新 Cache 之间存在时间间隔。 To avoid something wrong happening in this time gap Object is marked dirty before the Object A Changes.为了避免在这段时间内发生错误,在对象 A 更改之前将对象标记为脏对象。 So a request coming inbetween of these times will wait for dirty flag being cleared.因此,在这些时间之间发出的请求将等待脏标志被清除。

There is also a browser cache.还有一个浏览器缓存。 I remember ETAGS are used to validate this.我记得 ETAGS 用于验证这一点。 ETAG is the checksum of the resource. ETAG 是资源的校验和。 For this Client should maintain old ETAG value somehow.对于这个客户端应该以某种方式保持旧的 ETAG 值。 If the checksum of resource has changed then the new resource with HTTP 200 is sent else HTTP 304 (use local copy) is sent.如果资源的校验和已更改,则发送带有 HTTP 200 的新资源,否则发送 HTTP 304(使用本地副本)。

[Update] [更新]

PUT /companies/Nintendo PUT /公司/任天堂

GET /companies获取/公司

are two different resources.是两种不同的资源。 Your the cache for /companies/Nintendo is only expected to be updated and not /companies (I am talking of client side cache) when PUT /companies/Nintendo request is executed.当执行 PUT /companies/Nintendo 请求时,您的 /companies/Nintendo 缓存只会更新,而不是 /companies(我说的是客户端缓存)。 Suppose you call GET /companies/Nintendo next time, based on http headers the response is returned.假设您下次调用GET /companies/Nintendo ,根据 http 标头返回响应。 GET /companies is a brand new request as it points to different resource. GET /companies是一个全新的请求,因为它指向不同的资源。

Now question is what should be the http headers?现在的问题是 http 标头应该是什么? It is purely application specific.它纯粹是特定于应用程序的。 Suppose it is stock quote I would not cache.假设它是我不会缓存的股票报价。 Suppose it is NEWS item I would cache for certain time.假设它是我会缓存一段时间的新闻项目。 Your reference link http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html has all the details of Cache http headers.您的参考链接http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html包含缓存 http 标头的所有详细信息。 Only thing not mentioned much is ETag usage.唯一没有提到的就是 ETag 的使用。 ETag can have checksum of resource. ETag 可以有资源的校验和。 Check http://en.wikipedia.org/wiki/HTTP_ETag and also check https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers检查http://en.wikipedia.org/wiki/HTTP_ETag并检查https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM