网站首页 > 技术文章 正文
在之前的分享中,我们提到了SpringBoot的跨域操作,在描述跨域操作的时候,我们提到了一个预检请求的概念,那么什么是预检请求呢?
什么是预检请求
所谓的预检请求(Preflight Request)其实就是在跨域操作中的提供的一个安全确认机制,用于在实际的操作请求之前去校验目标服务器是否允许进行跨域请求操作。这种预检请求是由浏览器端自动发出,主要的作用就是确保服务器端能够允许客户端进行某些跨域的请求操作。
具体操作方法,当浏览器执行一个跨域请求的时候,如果这个请求中使用了某些方法(例如 PUT、DELETE 或 PATCH)或者包含了一些自定义的头部字段(例如 Authorization),那么浏览器就会在发送正式的实际请求之前,先去发送一个HTTP OPTIONS请求,这个请求其实就是我们所说的预检请求,也是在面试过程中经常被问到的问题。
预检请求的目的就是确保跨域请求的安全性,就需要服务器在预检请求中确认是否允许跨域请求的执行。如果服务器端是允许这个跨域请求操作,那么它就会在预检请求的响应中包含适当的CORS头部字段,比如Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers等信息来允许跨域操作。
为什么 POST 请求会发送两次请求?
POST 请求并不总是会发送两次请求,只有在以下情况下才会发送两次请求。
- 使用了非简单请求方法:简单请求方法包括GET、HEAD和POST,但POST请求如果包含了某些特殊的头部字段或内容类型(如application/json),则不再被视为简单请求。
- 包含了自定义头部字段:如果请求中包含了一些浏览器默认不会发送的头部字段,比如Authorization。
- 包含了非标准的内容类型:如果POST请求使用了除了application/x-www-form-urlencoded、multipart/form-data或text/plain之外的内容类型比如application/json。也就是说浏览器在这些请求情况下,会先发送一个预检请求,这样确定了服务器端允许相应的操作才开始发送相应的真实请求操作,如下所示。
举例说明
假设我们有一个前端应用要向https://example.com/api/data发送一个 POST 请求,包含JSON数据和Authorization头部,如下所示。
fetch('https://example.com/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
},
body: JSON.stringify({ key: 'value' })
})
.then(response => response.json())
.then(data => console.log(data));
由于这个请求包含了Content-Type: application/json和Authorization头部,浏览器会先发送一个预检请求,如下所示。
OPTIONS /api/data HTTP/1.1
Host: example.com
Origin: http://your-origin.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type, authorization
服务器响应这个预检请求,如果允许跨域请求,会返回如下信息。
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://your-origin.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: content-type, authorization
这个时候浏览器才会真正的发送一个POST请求进行调用。
这种机制可以有效的确保浏览器跨域请求的安全性,在一定程度上可以避免潜在的跨站请求伪造(CSRF)攻击等安全问题。
- 上一篇: 基于OAuth2的OIDC (OpenId Connect)身份认证
- 下一篇: 彻底理解JWT认证
猜你喜欢
- 2024-11-26 学会IDEA REST Client后,postman就可以丢掉了...
- 2024-11-26 IntelliJ IDEA 自带的高能神器
- 2024-11-26 java 程序员如何更高效地测试接口?
- 2024-11-26 JWT 简介
- 2024-11-26 就在刚刚,马斯克 xAI 正式公测 xAI API,每天赠送 25 美元免费积分!
- 2024-11-26 用Postman测试需要授权的接口
- 2024-11-26 全面解读跨域身份验证方案——JWT
- 2024-11-26 Rest API的认证模式
- 2024-11-26 istio 1.10学习笔记13: 使用认证策略设置双向TLS和终端用户认证
- 2024-11-26 写给运维的Nginx秘籍
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-