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预检请求。

相关推荐
代码对我眨眼睛13 分钟前
springboot从分层到解耦
spring boot·后端
The Straggling Crow22 分钟前
go 战略
开发语言·后端·golang
ai安歌28 分钟前
【JavaWeb】利用IDEA2024+tomcat10配置web6.0版本搭建JavaWeb开发项目
java·开发语言·后端·tomcat·web·intellij idea
dream_ready33 分钟前
linux安装nginx+前端部署vue项目(实际测试react项目也可以)
前端·javascript·vue.js·nginx·react·html5
编写美好前程34 分钟前
ruoyi-vue若依前端是如何防止接口重复请求
前端·javascript·vue.js
flytam35 分钟前
ES5 在 Web 上的现状
前端·javascript
喵喵酱仔__36 分钟前
阻止冒泡事件
前端·javascript·vue.js
GISer_Jing36 分钟前
前端面试CSS常见题目
前端·css·面试
尘浮生41 分钟前
Java项目实战II基于Java+Spring Boot+MySQL的作业管理系统设计与实现(源码+数据库+文档)
java·开发语言·数据库·spring boot·后端·mysql·spring
八了个戒1 小时前
【TypeScript入坑】什么是TypeScript?
开发语言·前端·javascript·面试·typescript