杭州网站建设第一品牌,鄂尔多斯市东胜区城市建设局网站,建筑公司网站怎么设计,网站怎么做统计如果您想知道是否可以缓存post请求#xff0c;并尝试研究该问题的答案#xff0c;那么您很可能不会成功。当搜索“缓存post请求”时#xff0c;第一个结果是这个StackOverflow问题。
答案是令人困惑的#xff0c;包括缓存应该如何工作#xff0c;缓存如何根据RFC工作并尝试研究该问题的答案那么您很可能不会成功。当搜索“缓存post请求”时第一个结果是这个StackOverflow问题。
答案是令人困惑的包括缓存应该如何工作缓存如何根据RFC工作缓存应该如何根据RFC工作以及缓存在实践中如何工作。让我们从RFC开始逐步演示浏览器的实际工作方式然后讨论CDN、GraphQL和其他值得关注的领域。
RFC 2616
根据RFCPOST请求必须使缓存无效
13.10 Invalidation After Updates or Deletions..Some HTTP methods MUST cause a cache to invalidate an entity. This is
either the entity referred to by the Request-URI, or by the Location
or Content-Location headers (if present). These methods are:- PUT- DELETE- POST
复制
这种语言表明POST请求是不可缓存的但事实并非如此(在本例中)。高速缓存仅对先前存储的数据无效。RFC (似乎)明确说明是的您可以缓存POST请求
9.5 POST..Responses to this method are not cacheable, unless the response
includes appropriate Cache-Control or Expires header fields. However,
the 303 (See Other) response can be used to direct the user agent to
retrieve a cacheable resource.
复制
尽管使用这种语言但设置Cache-Control时不得缓存对同一资源的后续POST请求。必须将POST请求发送到服务器
13.11 Write-Through Mandatory..All methods that might be expected to cause modifications to the
origin servers resources MUST be written through to the origin
server. This currently includes all methods except for GET and HEAD.
A cache MUST NOT reply to such a request from a client before having
transmitted the request to the inbound server, and having received a
corresponding response from the inbound server. This does not prevent
a proxy cache from sending a 100 (Continue) response before the
inbound server has sent its final reply.
复制
这怎么说得通呢您不是在缓存POST请求而是在缓存资源。
对于对同一资源的后续GET请求只能缓存POST响应正文。在POST响应中设置Location或Content-Location标头以传达正文所代表的资源。因此在技术上缓存POST请求的唯一有效方法是对相同资源的后续GET。
正确答案是两者兼而有之 “是的RFC允许您将后续GET的POST请求缓存到相同的resourceno。RFC不允许您缓存后续POST的POST请求因为POST不是幂等的必须直接写入服务器” 尽管RFC允许缓存对同一资源的请求但实际上浏览器和CDN不会实现此行为也不允许您缓存POST请求。
资料来源 https://www.rfc-editor.org/rfc/rfc2616#section-13 HTTP/1.1 RFChttps://www.mnot.net/blog/2012/09/24/caching_POST 浏览器行为演示
给定以下示例JavaScript应用程序(index.js)
const express require(express)
const app express()let count 0app.get(/asdf, (req, res) {countconst msg count is ${count}console.log(msg)res.set(Access-Control-Allow-Origin, *).set(Cache-Control, public, max-age30).send(msg)}).post(/asdf, (req, res) {countconst msg count is ${count}console.log(msg)res.set(Access-Control-Allow-Origin, *).set(Cache-Control, public, max-age30).set(Content-Location, http://localhost:3000/asdf).set(Location, http://localhost:3000/asdf).status(201).send(msg)}).set(etag, false).disable(x-powered-by).listen(3000, () {console.log(Example app listening on port 3000!)})
复制
并给出以下示例网页(index.html)
!DOCTYPE html
htmlheadscriptasync function getRequest() {const response await fetch(http://localhost:3000/asdf)const text await response.text()alert(text)}async function postRequest(message) {const response await fetch(http://localhost:3000/asdf,{method: post,body: { message },})const text await response.text()alert(text)}/script
/headbodybutton onclickgetRequest()Trigger GET request/buttonbr /button onclickpostRequest(trigger1)Trigger POST request (body 1)/buttonbr /button onclickpostRequest(trigger2)Trigger POST request (body 2)/button
/body/html
复制
安装NodeJS、Express并启动JavaScript应用程序。在浏览器中打开网页。尝试几种不同的方案来测试浏览器行为
每次单击Trigger GET request“时都会显示相同的 count”(HTTP高速缓存works).
Clicking Trigger POST request“每次都会触发不同的计数(用于POST的HTTP高速缓存不会work). Clicking Trigger GET request”、Trigger GET request“和Trigger GET request”显示POST请求使GET请求的cache. Clicking Trigger POST request“无效然后单击Trigger GET request”则显示浏览器不会为后续GET请求高速缓存POST请求即使这是允许的。 这表明即使您可以设置Cache-Control和Content-Location响应头也无法让浏览器缓存HTTP POST请求。
我必须遵循RFC吗
浏览器行为是不可配置的但如果您不是浏览器则不必受RFC规则的约束。
如果您正在编写应用程序代码没有什么可以阻止您显式缓存POST请求(伪代码)
if (cache.get(hello)) {return cache.get(hello)
} else {response post(url http://somewebsite/hello, request_body world)cache.put(hello, response.body)return response.body
}
复制
CDN、代理和网关也不必遵循RFC。例如如果您使用Fastly作为您的CDNFastly允许您将custom VCL逻辑写入cache POST requests。
我应该缓存POST请求吗
POST请求是否应该缓存取决于上下文。
例如您可以使用POST查询Elasticsearch或GraphQL其中您的底层查询是幂等的。在这些情况下缓存响应可能有意义也可能没有意义具体取决于用例。
在RESTful应用程序接口中POST请求通常创建一个资源不应该被缓存。这也是RFC对POST的理解它不是一个幂等操作。
GraphQL
如果您使用的是GraphQL并且需要跨CDN和浏览器进行HTTP缓存请考虑使用GET method而不是POST发送查询是否符合您的要求。需要注意的是不同的浏览器和CDN可能有不同的URI长度限制但是操作安全列表(查询白名单)作为面向外部的生产GraphQL应用程序的最佳实践可以缩短URI。