FrankKai.github.io
FrankKai.github.io copied to clipboard
如何理解HTTP方法的安全性,幂等性和缓存性?
在系统性学习OPTIONS请求的过程中,发现在这个请求头的描述信息中,除了reqeust是否有body,成功response是否有body以及是否在HTML forms中允许之外,还有3个没有注意过的HTTP方法的特性:安全性,幂等性和缓存性。
因此,这篇博文将来系统性学习一下这3个重要的HTTP方法的特性。
- 安全性
- 幂等性
- 缓存性
安全性
- HTTP的安全性是如何定义的?
- HTTP安全的method有哪些?
- 安全性与幂等性之间有什么关联?
- 安全性对于服务器来说有什么好处?
- 安全的方法仅仅用于获取静态文件吗?
- 安全性由前端保证还是服务端保证?
- 安全方法与不安全方法的比较
- 常见安全方法与不安全方法
HTTP的安全性是如何定义的?
如果一个HTTP method不更改服务器的状态,那么它就是safe的。 换句话说,如果一个method是仅仅执行read-only操作的,那么它就是safe的。
HTTP安全的method有哪些?
以下这些HTTP方法是安全的:GET,HEAD,OPTIONS。
安全性与幂等性之间有什么关联?
所有的安全方法都是幂等的。 但不是所有的幂等方法都是安全的,比如PUT和DELETE是幂等的,但是并不安全。
安全性对于服务器来说有什么好处?
即使安全的方法只是read-only的,但是服务器可以修改他们的状态:打印或者用于统计。 这里最重要的一点是:通过调用安全的方法,client不会不要求任何服务器更改自身,所以不会给服务器创建出没必要的加载或者负担。浏览器调用安全的方法的话,不用担心对服务器造成伤害;这使得浏览器可以无风险的执行pre-fetching。 web搜寻器也依赖于调用安全的方法。
安全的方法仅仅用于获取静态文件吗?
安全的方法不仅仅服务static文件。 可用于通知服务器生成安全脚本。(SSR) 一个server可以对一个即时的安全方法生成一个answer,只要生成的script是安全的:它不能出发副作用,例如在电商网站中触发一个订单。
安全性由前端保证还是服务端保证?
安全性由服务端保证,是web服务器(Apache,Nginx或IIS)。 应用程序不允许GET请求更改状态。
安全方法与不安全方法的比较
// 安全方法不改变服务器状态
GET /pageX.html HTTP/1.1
// 不安全方法改变服务器状态
POST /pageX.html HTTP/1.1
// 幂等但是不安全的方法
DELETE /idX/delete HTTP/1.1
常见安全方法与不安全方法
安全方法:GET
,HEAD
,OPTIONS
。
不安全方法:PUT
,DELETE
,POST
幂等性
- HTTP的幂等性是如何定义的?
- HTTP幂等的method有哪些?
- 如何做到HTTP幂等?
- 幂等方法与非幂等方法的比较
- 常见幂等方法与非幂等方法
HTTP的幂等性是如何定义的?
如果一个影响完全相同的请求发起一次或多次之后,而服务器的状态一直是保持一致的。那么这个请求就可以叫做幂等的。 换句话说,一个幂等方法不能有任何side-effects(除了刷新统计数据)。
HTTP幂等的method有哪些?
HTTP幂等的方法有GET,HEAD,PUT和DELETE,没有POST方法。 所有的安全方法都是幂等的,所以也包括OPTIONS。
如何做到HTTP幂等?
如果想要做到HTTP幂等,只有后端的真正的状态需要被考虑,每个请求的状态码可能会不同:第一个DELETE会返回200,而连续的请求会返回404。 另一个DELETE幂等的意义是开发者不能使用删除最后一个条目的DELETE方法实现RESTful API。 服务器不会保证方法幂等型,有些应用会打破幂等性的约束。
幂等方法与非幂等方法的比较
幂等方法多次调用,返回相同的结果。 非幂等方法调用多次,会导致增加多行。
// 幂等方法:GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
GET /pageX HTTP/1.1
// 非幂等方法:POST /add_row HTTP/1.1
POST /add_row HTTP/1.1
POST /add_row HTTP/1.1 -> 增加第二行
POST /add_row HTTP/1.1 -> 增加第三行
// 非幂等方法:DELETE /idX/delete HTTP/1.1
DELETE /idX/delete HTTP/1.1 -> 200
DELETE /idX/delete HTTP/1.1 -> 404
DELETE /idX/delete HTTP/1.1 ->404
常见幂等方法与非幂等方法
幂等方法:GET
,HEAD
,PUT
,DELETE
,OPTIONS
,TRACE
。
非幂等方法:POST
,PATCH
,CONNECT
。
缓存性
- HTTP的缓存性是如何定义的?
- response被缓存后可以做什么?
- 所有的HTTP response都可以被缓存吗?
- 非缓存请求使缓存失效
HTTP的缓存性是如何定义的?
HTTP的缓存性是指:如果一个HTTP response可以被缓存,那么这个响应就是cacheable的。
response被缓存后可以做什么?
response被缓存后,可用于查询和后续使用:比如向服务器发一个新的请求。
所有的HTTP response都可以被缓存吗?
不是。 HTTP response可以被缓存的规则如下:
- 自缓存方法GET,HEAD可缓存。 请求的方法是自缓存的(self cacheable)的话就可以缓存,例如GET和HEAD方法。
-
新鲜且设置Content-Location头的POST和PATCH可缓存。(不推荐) 如果指示是新鲜的而且
Content-Location
头有设置(很少有这么实现的),POST或PATCH请求的response同样可以被缓存。(firefox有个bug) - PUT和DELETE不能缓存。 PUT或DELETE方法是非可缓存方法,所以结果是不能缓存的。
-
响应状态码缓存 这些状态码的响应是可缓存的
200,203,204,206,300,301,404,405,410,414,501
。 - 响应头。 如果响应中没有特殊的类似Cache-Control的请求头,阻止缓存。
非缓存请求使缓存失效
有一些非缓存的请求或响应也许会使相同URI的缓存失效。 例如,一个PUT到pageX.html会使得所有的GET和HEAD请求失效:
GET /pageX.html HTTP/1.1
(…)
200 OK
(…)
PUT请求不能缓存。它会使得对同一个URI的HEAD或GET请求的缓存数据失效:
PUT /pageX.html HTTP/1.1
(…)
200 OK
(…)
再次使用GET请求时,在response的header中,Cache-Control的值为:no-cache
GET /pageX.html HTTP/1.1
(…)
200 OK
Cache-Control: no-cache
(…)
常见缓存方法和非缓存方法
缓存方法:GET
,HEAD
。
非缓存方法:PUT
,DELETE
,POST
。
参考资料: https://developer.mozilla.org/en-US/docs/Glossary/Safe https://developer.mozilla.org/en-US/docs/Glossary/Idempotent https://developer.mozilla.org/en-US/docs/Glossary/Cacheable