线上日志查到HTTP/1.1 412 Precondition Failed,一种追究下去,发现了很多关联的内容。

 

1. 412的响应值代表了什么?
问:
It is unclear to me when you should and should not return a HTTP 412: Precondition Failed, error for a web service? I am thinking of using it when validating data. For example, if a client POST's XML data and that data is missing a required data element, then responding with a 412 and a description of the error.
Does that align with the sprit of responding with an HTTP 412, or should something else be used (e.g. another http error code or web application exception)?

答:
 
If you look at RFC 2616 you'll see a number of request headers that can be used to apply conditions to a request:
If-Match
If-Modified-Since
If-None-Match
If-Range
If-Unmodified-Since
These headers contain 'preconditions', allowing the client to tell the server to only complete the request if certain conditions are met. For example, you use a PUT request to update the state of a resource, but you only want the PUT to be actioned if the resource has not been modified by someone else since your most recent GET.
The response status code 412 (Precondition Failed) is typically used when these preconditions fail.
Your example sounds like an invalid request (i.e. the client has submitted data that is invalid because of missing values). A status code of 400 (Bad Request) is more appropriate here IMO.

2. Conditional GET Request(缓存协商)

2.1 Conditional GET Request

The HTTP Protocol defines a caching mechanism, in which the proxy web-servers can cache pages, files, images etc. Since caching is in place, There is a method which the servers are asked to return the document, either the “cached” or “live” document.
This request of asking the server for a document considering a specific parameter is called a Conditional GET Request. In this request, a specific request header is sent If-Modified-Since. This header sends a RFC 2822 formatted date as the value. The proxy which is between the Server and the client checks the date, and the cached document, if the condition matches, A 304 Not Modified header is sent back to the client in the response.
So consider a document /sample.html on example.com. Consider the very first request of the Client, Since this is the first request, the client does not know about the modified time, etc…
Here goes the request header as follows…
GET /sample.html HTTP/1.1
Host: example.com
Now the response that comes from the server is the document with the response headers. The response headers would be…
HTTP/1.x 200 OK
Via: The-proxy-name
Content-Length: 32859
Expires: Tue, 27 Dec 2005 11:25:11 GMT
Date: Tue, 27 Dec 2005 05:25:11 GMT
Content-Type: text/html; charset=iso-8859-1
Server: Apache/1.3.33 (Unix) PHP/4.3.10
Cache-Control: max-age=21600
Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT
Etag: “4135cda4″
Lets check what these headers mean..
    •    Cache-Control: It tells the client the maximum time in seconds to cache the document.
    •    Last-Modified: The document’s last modified date
    •    Etag: A unique hash for the document.
Once the Server responds, the client caches the document and stores it for the specified amount of time, In this case for 21600 seconds.
Next time when the user calls for the same document /sample.html within the specified cache time frame. The browser(client) will make a conditional get request, try to ask the server that if the document is modified after the specified time zone whose hashed value was the Etag value, ONLY THEN return a new document or else confirm that it is an old document.
So the request header would be as…
GET /sample.html HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 01 Sep 2004 13:24:52 GMT
If-None-Match: “4135cda4″
The header is self explanatory, it is asking for a new document which modified after Wed, 01 Sep 2004 13:24:52. The If-None-Match specifies that the client has mapped the document with that Entity value. RFC 2616 specifies that if If-None-Match is not accompanied with If-Modified-Since then the server must not send a 304 (Not Modified) header.(当客户请求头中只包含If-None-Match而不包含If-Modified-Since,那么服务端是不准返回304的。)
The response to the above request would be as.
HTTP/1.x 304 Not Modified
Via: The-proxy-server
Expires: Tue, 27 Dec 2005 11:25:19 GMT
Date: Tue, 27 Dec 2005 05:25:19 GMT
Server: Apache/1.3.33 (Unix) PHP/4.3.10
Keep-Alive: timeout=2, max=99
Etag: “4135cda4″
Cache-Control: max-age=21600
The server confirms the that the document is not modified and sends a 304 Not Modified header.
The client checks the 304 response header, and renders the document from the cache.

2.2 Conditional GET Request 理解
Conditional GET Request 就是常说的缓存协商。既然是协商 肯定是二个主体,指服务器与浏览器之间的协商。
对于静态元素,服务端根据它的最后一次修改时间(可以通过stat命令获取)判断
对于动态页面,需要在程序中进行判断.

协商首先要区别哪些是服务端返回指令。哪些是浏览器请求指令。象expire,max-age,Last-Modified,Etag都是服务端返回的指令。If-Match等IF开头的指令都是浏览器请求指令。会者不会用到前者的指令,但是会用到前者的指令值。
比如If-None-Match的值就是etag指令的值, If-Modified-Since的值就是Last-Modified指令的值。这样协商就变成你当初告诉我的现在还成立吗?

3.  F5 / Ctrl F5 /转到与Conditional GET Request(缓存协商)的关系

3.1 为什么Ctrl+F5明显要让网页Refresh慢一些?
在浏览器里中,按F5键或者点击Toobar上的Refresh/Reload图标(简称F5),和做F5同时按住Ctrl键(简称Ctrl+F5),效果是明显不一样的,通常Ctrl+F5明显要让网页Refresh慢一些,到底两者有什么区别呢?
 HTTP Headers 里有Expires、Last-Modified/If-Modified-Since和ETag/If-None-Match这些字段,F5/Ctrl+F5和这些有莫大关系。
假如我第一次访问过http://www.test.com,这个网页是个动态网页,每次访问都会去访问Server,但是它包含一个一个静态资源http://www.test.com/logo.gif,浏览器在显示这个网页之前需要发HTTP请求获取这个logo.gif文件,返回的HTTP response包含这样的Headers:
Expires: Thu 27 Nov 2008 07:00:00 GMT
Last-Modified: Fri 30 Nov 2007 00:00:00 GMT
那么浏览器就会cache住这个logo.gif文件,直到2008年11月27日7点整,或者直到用户有意清空cache。
下次我再通过bookmark或者通过在URI输入栏直接敲字的方法访问http://www.test.com的时候,浏览器一看本地有个logo.gif,而且它还没过期呢,就不会发HTTP request给server,而是直接把本地cache中的logo.gif显示了。
F5的作用和直接在URI输入栏中输入然后回车是不一样的,F5会让浏览器无论如何都发一个HTTP Request给Server,即使先前的Response中有Expires Header。所以,当我在当前http://www.test.com网页中按F5的时候,浏览器会发送一个HTTP Request给Server,但是包含这样的Headers:
If-Modified-Since: Fri 30 Nov 2007 00:00:00 GMT
实际上Server没有修改这个logo.gif文件,所以返回一个304 (Not Modified),这样的Response很小,所以round-trip耗时不多,网页很快就刷新了。
上面的例子中没有考虑ETag,最好就不要用ETag,但是如果Response中包含ETag,F5引发的Http Request中也是会包含If-None-Match的。

那么Ctrl+F5呢? Ctrl+F5要的是彻底的从Server拿一份新的资源过来,所以不光要发送HTTP request给Server,而且这个请求里面连If-Modified-Since/If-None-Match都没有,这样就逼着Server不能 返回304,而是把整个资源原原本本地返回一份,这样,Ctrl+F5引发的传输时间变长了,自然网页Refresh的也慢一些。
实 际上,为了保证拿到的是从Server上最新的,Ctrl+F5不只是去掉了If-Modified-Since/If-None-Match, 还需要添加一些HTTP Headers。(Ctrl+F5与F5的区别,去掉Conditional GET Request的指令,增加了Cache-Control: max-age=0这样的指令 )按照HTTP/1.1协议,Cache不光只是存在Browser终端,从Browser到Server之间的中间节点(比如 Proxy)也可能扮演Cache的作用,为了防止获得的只是这些中间节点的Cache,需要告诉他们,别用自己的Cache敷衍我,往Upstream 的节点要一个最新的copy吧。

ctrl+F5时不同浏览器的头指令:
在IE6中,Ctrl+F5会添加一个Header
Pragma: no-cache
在Firefox 2.0中,Ctrl+F5会添加两个
Pragma: no-cache
Cache-Control: max-age=0
注意max-age=0与no-cache的区别就是前者会一直要求client到backend上的各个节点的缓存内容过期( revalidate cache-entry), 而后者直接是client到backend的请求.禁止使用varnish等缓存内容.

3.2 各种刷新的区别:
3.2.1 Conditional GET Request的目的就是通过请求和[快速]响应(304响应的包很小)进行缓存协商。

3.2.2 Ctrl+F5不会使用Conditional GET Request指令。因为不需要协商。但是会直接请求服务端的内容。
F5,Refresh会使用使用Conditional GET Request指令, IF指令的值是服务端第一次响应返回的Last-Modified,Etag的值。就好比向另一个人确认最初告诉我的内容是否还有用。类F5操作不会用到第一次返回的Expires, max-age。因为它主要用来协商。
3.2.3地址栏输入地址&& 转到 都不需要协商,如果没过期,不发请求。直接通过expires,max-age判断本地缓存内容是否过期。

所以类F5与Ctrl+ F5的的一个明显区别就是带不带Condition Get的头,比如If-Modified-Since,if-None-Match. 转到与其它方式显著区别是首先判断本地是否过期,未过期直接使用本地缓存的内容,不会象F5不判断直接发送Condition Get请求。

Conditional GET Request(缓存协商)相关推荐

  1. 浏览器缓存:memory cache、disk cache、强缓存协商缓存等概念

    文章目录 分类 memory cache disk cache Service Worker Push Cache 缓存过程 强缓存 1.Expires 2.Cache-Control Expires ...

  2. 浏览器-缓存(协商缓存和强制缓存)

    1.强制缓存 [1]定义 强制缓存就是说在第一次访问服务器获取到数据之后,在过期时间以内不会去重复请求,而是通过浏览器缓存拿去数据: 过期时间:在响应头中存在一个属性 http1.1版本 :强制缓存通 ...

  3. HTTP缓存机制及原理(强制缓存/协商缓存)

    可以参考文章:https://www.imooc.com/article/267319#comment 主要感觉里面的图很好. 强制缓存(Expires/Cache-Control): 协商缓存: 1 ...

  4. 浏览器缓存和HTTP缓存协商

    简单来说,浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中.缓存会根据进来的请求保存输出内容的副本.当下一个请求来到的时候,如果是相同的URL ...

  5. 【计算机网络】前后端分离,HTTP协议,网络分层结构,TCP,强缓存/协商缓存

    ❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客

  6. 浏览器Disk Cache磁盘缓存及其协商缓存、及原生App和浏览器实现缓存的差异

    浏览器Disk Cache磁盘缓存及其协商缓存.及原生App和浏览器实现缓存的差异 目录 浏览器Disk Cache磁盘缓存及其协商缓存.及原生App和浏览器实现缓存的差异 1.Memory Cach ...

  7. 浏览器缓存:强缓存和协商缓存

    1. 强缓存,不向服务器发请求,直接从本地硬盘(from disk cache/from memory cache)或者内存中获取 2.协商缓存,向服务器发出验证,如果资源无更改,不重新返回资源内容, ...

  8. http协商缓存VS强缓存

    之前一直对浏览器缓存只能描述一个大概,深层次的原理不能描述上来:终于在前端的两次面试过程中被问倒下,为了泄恨,查阅一些资料最终对其有了一个更深入的理解,废话不多说,赶紧来看看浏览器缓存的那些事吧,有不 ...

  9. 你知道304吗?图解强缓存和协商缓存

    http协议-常见状态码,请求方法,http头部,http缓存 一.http状态码 1.引例阐述 2.状态码分类 3.常见状态码 4.关于协议和规范 二.http 方法 1.传统的methods 2. ...

  10. HTTP协商缓存与HTTP强缓存

    1.浏览器缓存 缓存这东西,第一次必须获取到资源后,然后根据返回的信息来告诉如何缓存资源,可能采用的是强缓存,也可能告诉客户端浏览器是协商缓存,这都需要根据响应的header内容来决定的.下面用两幅图 ...

最新文章

  1. LeetCode-35. Search Insert Position
  2. storm基础系列之五---------接入数据收集系统flume
  3. 一篇文章教你读懂Spring @Conditional注解
  4. Django框架(12.Django中模型类高阶查询(Q对象以及F对象 和聚合函数查询))
  5. 力扣- -231. 2的幂
  6. oracle,sqlserver,mysql区别
  7. 记录一些关于操作数据库(本地和linux服务器)常用的命令
  8. updateStateByKey算子入门案例之wordCount
  9. 读图,特征提取——形状
  10. 基于百度云AI开发车型识别车牌识别案例详解
  11. HTML+CSS 制作下拉菜单
  12. 灰度化处理——灰度化
  13. bzoj 1260 (区间dp)
  14. 正向代理与反向代理详解
  15. Moss到底算不算叛逃?
  16. Local Linear Model, Semi Local Linear Model and Local Level Model of TFP.STS
  17. AngularJs实战(六)
  18. windows embed sapi php,19.1 嵌入式SAPI
  19. 如何用js对url做urlencoding处理?
  20. 四川店盈通电子商务有限公司:《零售的哲学》中的最基本观点“以用户为中心”

热门文章

  1. 概率图模型(PGM)学习笔记(一)动机与概述
  2. 【概率论】期望、方差、协方差、相关系数、相关与独立、样本估计量、点估计、区间估计
  3. 编译原理完整学习笔记(三):词法分析
  4. 基础集合论 第二章 9 族
  5. 记忆测试系统c语言,c语言重点回忆
  6. 只需一个技巧,用手机轻松拍出震撼广角风景照
  7. [Hadoop]-Yarn-调度器篇
  8. 《浪潮之巅》读书笔记(上)
  9. xcode 9.0 iOS 11
  10. 配置generatorConfig.xml自动生成的代码的sql书写问题