简单请求与预检请求

预检请求

什么是预检请求?

对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

什么情况下会有预检请求

请求会对服务器有影响的会先法预检请求

当请求满足下述任一条件时,即应首先发送预检请求:

  • 使用了下面任一 HTTP 方法:
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (需要注意额外的限制)
    • [DPR](http://httpwg.org/http-extensions/client-hints.html#dpr)
    • [Downlink](http://httpwg.org/http-extensions/client-hints.html#downlink)
    • [Save-Data](http://httpwg.org/http-extensions/client-hints.html#save-data)
    • [Viewport-Width](http://httpwg.org/http-extensions/client-hints.html#viewport-width)
    • [Width](http://httpwg.org/http-extensions/client-hints.html#width)
  • Content-Type的值不属于下列之一:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • 请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
  • 请求中使用了ReadableStream对象。

简单请求

什么是简单请求?

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

什么请求是简单请求

按照预检请求的理解,简单请求就是对服务器无副作用的请求。

  • 使用下列方法之一:
  • Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (需要注意额外的限制)
    • [DPR](http://httpwg.org/http-extensions/client-hints.html#dpr)
    • [Downlink](http://httpwg.org/http-extensions/client-hints.html#downlink)
    • [Save-Data](http://httpwg.org/http-extensions/client-hints.html#save-data)
    • [Viewport-Width](http://httpwg.org/http-extensions/client-hints.html#viewport-width)
    • [Width](http://httpwg.org/http-extensions/client-hints.html#width)
  • Content-Type的值仅限于下列三者之一:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded
  • 请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。
  • 请求中没有使用 ReadableStream 对象。

POST为什么分简单和不简单

**

**搭配某些 MIME 类型的 POST 请求,**需要发送预检请求,怎么理解?
为什么POST请求划分到简单请求里?

为什么content-type为下面三种的却被视为简单请求,工作中碰到的post请求很多都会采用下面的格式,且会修改数据库内容,其不会存在安全风险吗?

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

如果我们现在重新设计整个HTTP协议,我们可以要求浏览器在发送任何数据到另外一个域的服务器之前,都必须先发送preflight request。但是大部分现存网站并未针对preflight request做出实现,所以这意味着现有的互联网中,如果一个域的表单向另一个域提交的时候会跨域失败,直到目标网站更新处理perflight request为止。

所以在我们制定这一新的标准的时候,应当考虑到目前互联网已经存在这样的请求,他们虽然看起来可能不安全,但为了向下兼容,我们不能强制对这些请求做preflight request。既然不能强制做preflight request验证,那发这个东西就没有什么意义了。

可能是为了向下兼容表单提交吧,表单提交出现比同源策略要早。


参考mdn
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
知乎
https://www.zhihu.com/question/268998684

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
进行非简单请求时,浏览器会先发送一个预检请求OPTIONS,以确保实际请求是安全的并且被服务器支持。预检请求包含一个Access-Control-Request-Method头部,用于指定实际请求的HTTP方法。 正确处理预检请求,需要在服务器端设置相应的CORS响应头。具体步骤如下: 1. 在springboot的配置类中,添加CorsFilter过滤器。 ```java @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); // 允许跨域访问的域名,*代表所有域名 config.addAllowedHeader("*"); // 允许跨域访问的请求头 config.addAllowedMethod("*"); // 允许跨域访问的HTTP方法,*代表所有方法 config.setMaxAge(1800L); // 预检请求的缓存时间,单位为秒 source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } ``` 2. 配置CorsConfiguration对象,设置允许的跨域访问域名、请求头和HTTP方法。其中,addAllowedOrigin方法设置允许跨域访问的域名,addAllowedHeader方法设置允许跨域访问的请求头,addAllowedMethod方法设置允许跨域访问的HTTP方法。 3. 将CorsConfiguration对象注册到UrlBasedCorsConfigurationSource中,并设置拦截路径。在本示例中,将拦截所有请求,所以设置拦截路径为"/**"。 4. 将UrlBasedCorsConfigurationSource对象注册到CorsFilter中,并返回该对象。 这样,当浏览器发送预检请求时,CorsFilter会对该请求进行拦截,并返回相应的CORS响应头,以确保实际请求可以被安全地执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值