Restful规范是否需要遵守?全用Post请求?为什么Post会发两次请求?

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预检的请求称为简单请求,满足以下所有条件的才会被视为简单请求:

  1. 使用GET、POST、HEAD其中一种方法

  2. 只使用了如下的安全首部字段,不得人为设置其他首部字段

    • 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

  3. 请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问

  4. 请求中没有使用 ReadableStream 对象

总结一下:可以简单的理解为没有人为设置一些字段的Get和Post都是简单请求

预检请求


简单点理解,只要不是简单请求,基本上就都会触发预检

  1. 使用了PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH方法
  2. 人为设置了非规定内的其他首部字段,参考上面简单请求的安全字段集合,还要特别注意Content-Type的类型
  3. XMLHttpRequestUpload 对象注册了任何事件监听器
  4. 请求中使用了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预检请求。

相关推荐
小小小小宇12 分钟前
前端模拟一个setTimeout
前端
萌萌哒草头将军16 分钟前
🚀🚀🚀 不要只知道 Vite 了,可以看看 Farm ,Rust 编写的快速且一致的打包工具
前端·vue.js·react.js
bobz9651 小时前
vxlan 为什么一定要封装在 udp 报文里?
后端
bobz9651 小时前
vxlan 直接使用 ip 层封装是否可以?
后端
芝士加1 小时前
Playwright vs MidScene:自动化工具“双雄”谁更适合你?
前端·javascript
Carlos_sam2 小时前
OpenLayers:封装一个自定义罗盘控件
前端·javascript
前端南玖2 小时前
深入Vue3响应式:手写实现reactive与ref
前端·javascript·vue.js
wordbaby3 小时前
React Router 双重加载器机制:服务端 loader 与客户端 clientLoader 完整解析
前端·react.js
itslife3 小时前
Fiber 架构
前端·react.js
郑道3 小时前
Docker 在 macOS 下的安装与 Gitea 部署经验总结
后端