FrankKai / FrankKai.github.io

FE blog
https://frankkai.github.io/
362 stars 39 forks source link

如何理解HTTP方法的安全性,幂等性和缓存性? #238

Open FrankKai opened 3 years ago

FrankKai commented 3 years ago

在系统性学习OPTIONS请求的过程中,发现在这个请求头的描述信息中,除了reqeust是否有body,成功response是否有body以及是否在HTML forms中允许之外,还有3个没有注意过的HTTP方法的特性:安全性,幂等性和缓存性。

因此,这篇博文将来系统性学习一下这3个重要的HTTP方法的特性。

安全性

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的幂等性是如何定义的?

如果一个影响完全相同的请求发起一次或多次之后,而服务器的状态一直是保持一致的。那么这个请求就可以叫做幂等的。 换句话说,一个幂等方法不能有任何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的缓存性是如何定义的?

HTTP的缓存性是指:如果一个HTTP response可以被缓存,那么这个响应就是cacheable的。

response被缓存后可以做什么?

response被缓存后,可用于查询和后续使用:比如向服务器发一个新的请求。

所有的HTTP response都可以被缓存吗?

不是。 HTTP response可以被缓存的规则如下:

非缓存请求使缓存失效

有一些非缓存的请求或响应也许会使相同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