Restful规范是否需要遵守?为什么post会发两次请求?
回顾Post和Get请求的区别
最近在社区、掘金等发现一个讨论:为什么有点公司规定所有接口都用POST请求?Rest风格是否是规定?
-
先回顾一下Get请求和Post请求点一些区别
1.Post请求相对Get请求会更加的安全 (Post请求不会作为url的一部分,不会被缓存,不会被保存在服务器日志及浏览器日志中)
2.Post请求能发送的数据会更大更多 (Get请求的url是有长度限制的)
3.Post请求的速度慢于Get请求
4.Post一般用于修改和写入数据,Get一般用于搜索获取数据
5.Get请求的是静态资源 (视频、音频之类的),会进行缓存,如果是数据,则不会进行缓存
总结一下:Post在发送数据量大的请求时优势很明显,Get请求则更适合获取静态资源和简单点查询接口
Restful的好处
Restful能明确列出来的好处 (并不全面):
- 表达不同的业务动作语义 (Post /api/obj 和 Put /api/obj),可以是相同的接口地址,不同类型的请求
- 使用URI来表示资源,这使得它容易被理解和记忆
- 使用HTTP状态码来表示操作的结果,这使得它容易被理解和处理
总结一下:Restful架构提供了一种简单、统一的方式来创建Web服务,使得它易于被理解和使用
是否要用Restful接口
在看到有一篇文章中的一位大佬给了一个中肯的答案
我的理解是:用不用Restful风格的接口取决于整体项目的发展,如果说都用Post请求能提高效率,就不需要Restful了
如果说在对业务啊,对日后的更新迭代等,没有影响且开发效率和Post情况相当的情况下,可以使用Restful风格的接口
毕竟使用Restful风格的接口,能够让业务更加的语义化,且更加容易维护
思考
我在一些关于Restful风格的文章下面看到一些评论
看到评论区有人说到OPTIONS预检请求,那么什么是OPTIONS遇见请求呢?这跟Post会发两次请求有关
Post为什么会发两次请求?什么是预检请求?
CORS是属于的跨域问题,跟同源策略 有关,如果还不知道同源策略的,可以先去看看同源策略,本文不再赘述
要引出为什么Post会发送两次请求,首先我们必须得回顾一下CORS,因为预检请求和跨域是直接关联的
跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源 (这点和下面关联起来了)
规范中要求,对那些可能对服务器数据产生副作用的HTTP请求方法 (特别是Get以外的Http请求,或者是Restful类型的Post请求)
浏览器必须首先使用 OPTIONS 方法发起一个预检请求 (preflight request) ,从而获知服务端是否允许该跨域请求
当服务器确认允许该跨域请求后,才真正的发起实际的HTTP请求
什么时候会触发OPTIONS预检请求
简单请求
不会触发OPTIONS预检的请求称为简单请求,满足以下所有条件的才会被视为简单请求:
-
使用
GET、POST、HEAD
其中一种方法 -
只使用了如下的安全首部字段,不得人为设置其他首部字段
-
Accept
-
Accept-Language
-
Content-Language
-
Content-Type
仅限以下三种
text/plain
multipart/form-data
application/x-www-form-urlencoded
-
HTML头部header field字段:
DPR、Download、Save-Data、Viewport-Width、WIdth
-
-
请求中的任意
XMLHttpRequestUpload
对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问 -
请求中没有使用 ReadableStream 对象
总结一下:可以简单的理解为没有人为设置一些字段的Get和Post都是简单请求
预检请求
简单点理解,只要不是简单请求,基本上就都会触发预检
- 使用了
PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH
方法 - 人为设置了非规定内的其他首部字段,参考上面简单请求的安全字段集合,还要特别注意
Content-Type
的类型 XMLHttpRequestUpload
对象注册了任何事件监听器- 请求中使用了
ReadableStream
对象
思考与疑问
-
OPTIONS预检请求是否会每次都需要执行?
OPTIONS预检是有可能执行多次的
举个例子,在预检请求发出后,服务端回去校验比如说你的一个头信息 "Access-Control-Allow-Origin"
如果服务器返回说可以进行跨域访问,那么预检请求就是成功的。
当你这第一次预检请求成功后,浏览器会自动将这次预检请求进行缓存,如果第二次包括之后的HTTP与上一次OPTIONS的缓存
结果差别较大的话,第二次OPTIONS预检请求就会被发送
-
如何避免多次预检请求?
1.设置响应头Cache-Control为max-age=0,以避免浏览器缓存OPTIONS预检请求的结果。
2.在实际的HTTP请求中添加相同的预检请求头,以告诉浏览器该请求与上一次的OPTIONS预检请求相似度较高,可以重用缓存。
3.使用CORS中间件,如ServiceWorker等,来处理OPTIONS预检请求,从而避免浏览器发送第二次OPTIONS预检请求。