从前后端的角度分析options预检请求 环球微动态

2023-05-16 15:25:19 博客园
摘要:options预检请求是干嘛的?options请求一定会在post请求之前发送吗?前端或者后端开发需要手动干预这个预检请求吗?不用文档定义堆砌名词,从前后端角度单独分析,大白话带你了解!

本文分享自华为云社区《从前后端的角度分析options预检请求——打破前后端联调的理解障碍》,作者: 砖业洋__ 。

options预检请求是干嘛的?options请求一定会在post请求之前发送吗?前端或者后端开发需要手动干预这个预检请求吗?不用文档定义堆砌名词,从前后端角度单独分析,大白话带你了解!


(相关资料图)

从前端的角度看options——post请求之前一定会有options请求?信口雌黄!

你是否经常看到这种跨域请求错误?

这是因为服务器不允许跨域请求,这里会深入讲一讲OPTIONS请求。

只有在满足一定条件的跨域请求中,浏览器才会发送OPTIONS请求(预检请求)。这些请求被称为“非简单请求”。反之,如果一个跨域请求被认为是“简单请求”,那么浏览器将不会发送OPTIONS请求。

简单请求需要满足以下条件:

只使用以下HTTP方法之一:GET、HEAD或POST。只使用以下HTTP头部:Accept、Accept-Language、Content-Language、Content-Type。Content-Type的值仅限于:application/x-www-form-urlencoded、multipart/form-data或text/plain。

如果一个跨域请求不满足以上所有条件,那么它被认为是非简单请求。对于非简单请求,浏览器会在实际请求(例如PUT、DELETE、PATCH或具有自定义头部和其他Content-Type的POST请求)之前发送OPTIONS请求(预检请求)。

举个例子吧,口嗨半天是看不懂的,让我们看看POST请求在什么情况下不发送OPTIONS请求

提示:当一个跨域POST请求满足简单请求条件时,浏览器不会发送OPTIONS请求(预检请求)。以下是一个满足简单请求条件的POST请求示例:

// 使用Fetch API发送跨域POST请求fetch("https://example.com/api/data", {  method: "POST",  headers: { "Content-Type": "application/x-www-form-urlencoded" },  body: "key1=value1&key2=value2"}) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error("Error:", error));

在这个示例中,我们使用Fetch API发送了一个跨域POST请求。请求满足以下简单请求条件:

使用POST方法。使用的HTTP头部仅包括Content-Type。Content-Type的值为"application/x-www-form-urlencoded",属于允许的三种类型之一(application/x-www-form-urlencoded、multipart/form-data或text/plain)。

因为这个请求满足了简单请求条件,所以浏览器不会发送OPTIONS请求(预检请求)。

我们再看看什么情况下POST请求之前会发送OPTIONS请求,同样用代码说明,进行对比

提示:在跨域请求中,如果POST请求不满足简单请求条件,浏览器会在实际POST请求之前发送OPTIONS请求(预检请求)。

// 使用Fetch API发送跨域POST请求fetch("https://example.com/api/data", {  method: "POST",  headers: { "Content-Type": "application/json", "X-Custom-Header": "custom-value" },  body: JSON.stringify({    key1: "value1",    key2: "value2" })}) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error("Error:", error));

在这个示例中,我们使用Fetch API发送了一个跨域POST请求。请求不满足简单请求条件,因为:

使用了非允许范围内的Content-Type值("application/json" 不属于 application/x-www-form-urlencoded、multipart/form-data或text/plain)。使用了一个自定义HTTP头部 “X-Custom-Header”,这不在允许的头部列表中。

因为这个请求不满足简单请求条件,所以在实际POST请求之前,浏览器会发送OPTIONS请求(预检请求)。

你可以按F12直接在Console输入查看Network,尽管这个网址不存在,但是不影响观察OPTIONS请求,对比一下我这两个例子。

总结:当进行非简单跨域POST请求时,浏览器会在实际POST请求之前发送OPTIONS预检请求,询问服务器是否允许跨域POST请求。如果服务器不允许跨域请求,浏览器控制台会显示跨域错误提示。如果服务器允许跨域请求,那么浏览器会继续发送实际的POST请求。而对于满足简单请求条件的跨域POST请求,浏览器不会发送OPTIONS预检请求。

后端可以通过设置Access-Control-Max-Age来控制OPTIONS请求的发送频率。OPTIONS请求没有响应数据(response data),这是因为OPTIONS请求的目的是为了获取服务器对于跨域请求的配置信息(如允许的请求方法、允许的请求头部等),而不是为了获取实际的业务数据,OPTIONS请求不会命中后端某个接口。因此,当服务器返回OPTIONS响应时,响应中主要包含跨域配置信息,而不会包含实际的业务数据

本地调试一下,前端发送POST请求,后端在POST方法里面打断点调试时,也不会阻碍OPTIONS请求的返回

从后端的角度看options——post请求之前一定会有options请求?胡说八道!

在配置跨域时,服务器需要处理OPTIONS请求,以便在响应头中返回跨域配置信息。这个过程通常是由服务器的跨域中间件(Node.js—Express框架的cors中间件、Python—Flask框架的flask_cors扩展)或过滤器(Java—SpringBoot框架的跨域过滤器)自动完成的,而无需开发人员手动处理。

以下是使用Spring Boot的一个跨域过滤器,供参考

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource;import org.springframework.web.filter.CorsFilter;@Configurationpublic class CorsConfig { public CorsConfig() { } @Bean public CorsFilter corsFilter() { // 1. 添加cors配置信息 CorsConfiguration config = new CorsConfiguration(); // Response Headers里面的Access-Control-Allow-Origin: http://localhost:8080 config.addAllowedOrigin("http://localhost:8080"); // 其实不建议使用*,允许所有跨域 config.addAllowedOrigin("*"); // 设置是否发送cookie信息,在前端也可以设置axios.defaults.withCredentials = true;表示发送Cookie, // 跨域请求要想带上cookie,必须要请求属性withCredentials=true,这是浏览器的同源策略导致的问题:不允许JS访问跨域的Cookie /**         * withCredentials前后端都要设置,后端是setAllowCredentials来设置         * 如果后端设置为false而前端设置为true,前端带cookie就会报错         * 如果后端为true,前端为false,那么后端拿不到前端的cookie,cookie数组为null         * 前后端都设置withCredentials为true,表示允许前端传递cookie到后端。         * 前后端都为false,前端不会传递cookie到服务端,后端也不接受cookie         */ // Response Headers里面的Access-Control-Allow-Credentials: true config.setAllowCredentials(true); // 设置允许请求的方式,比如get、post、put、delete,*表示全部 // Response Headers里面的Access-Control-Allow-Methods属性 config.addAllowedMethod("*"); // 设置允许的header // Response Headers里面的Access-Control-Allow-Headers属性,这里是Access-Control-Allow-Headers: content-type, headeruserid, headerusertoken config.addAllowedHeader("*"); // Response Headers里面的Access-Control-Max-Age:3600 // 表示下回同一个接口post请求,在3600s之内不会发送options请求,不管post请求成功还是失败,3600s之内不会再发送options请求 // 如果不设置这个,那么每次post请求之前必定有options请求 config.setMaxAge(3600L); // 2. 为url添加映射路径 UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource(); // /**表示该config适用于所有路由 corsSource.registerCorsConfiguration("/**", config); // 3. 返回重新定义好的corsSource return new CorsFilter(corsSource); }}

这里setMaxAge方法来设置预检请求(OPTIONS请求)的有效期,当浏览器第一次发送非简单的跨域POST请求时,它会先发送一个OPTIONS请求。如果服务器允许跨域,并且设置了Access-Control-Max-Age头(设置了setMaxAge方法),那么浏览器会缓存这个预检请求的结果。在Access-Control-Max-Age头指定的时间范围内,浏览器不会再次发送OPTIONS请求,而是直接发送实际的POST请求,不管POST请求成功还是失败,在设置的时间范围内,同一个接口请求是绝对不会再次发送OPTIONS请求的。

后端需要注意的是,我这里设置允许请求的方法是config.addAllowedMethod("*"),*表示允许所有HTTP请求方法。如果未设置,则默认只允许“GET”和“HEAD”。你可以设置的HTTPMethod为GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE

经过我的测试,OPTIONS无需手动设置,因为单纯只设置OPTIONS也无效。如果你设置了允许POST,代码为config.addAllowedMethod(HttpMethod.POST); 那么其实已经默认允许了OPTIONS,如果你只允许了GET,尝试发送POST请求就会报错。

举个例子,这里只允许了GET请求,当我们尝试发送一个POST非简单请求,预检请求返回403,服务器拒绝了OPTIONS类型的请求,因为你只允许了GET,未配置允许OPTIONS请求,那么浏览器将收到一个403 Forbidden响应,表示服务器拒绝了该OPTIONS请求,POST请求的状态显示CORS error

在Spring Boot中,配置允许某个请求方法(如POST、PUT或DELETE)时,OPTIONS请求通常会被自动允许。这意味着在大多数情况下,后端开发人员不需要特意考虑OPTIONS请求。这种自动允许OPTIONS请求的行为取决于使用的跨域处理库或配置,最好还是显式地允许OPTIONS请求。

点击关注,第一时间了解华为云新鲜技术~

标签:

相关文章

从前后端的角度分析options预检请求 环球微动态

options预检请求是干嘛的?options请求一定会在post请求之前发送吗?前端或者后端开发需要手动干预这个预检

2023-05-16

2023三伏时间表:具体什么时候入伏出伏?附初伏中伏末伏具体时间! 天天观速讯

进入5月下旬后,我国各地气候逐步炎热,届时将迎来一年一度最热的三伏天,而这段时间对人们的生活和健康有

2023-05-16

中外科研团队捕获快速射电暴关键信息_观天下

科技日报讯(记者何星辉实习生付菁)世界首例持续活跃快速射电暴FRB20190520B被中国天眼发现后,中外科研团

2023-05-16

4月以来河南发生飞絮火情900余起 专家提醒加强防范|当前播报

随着气温持续升高,很多地方又飘起了杨柳絮。5月2日,河南省济源市消防救援支队济渎路特勤站在处置飞絮引发

2023-05-16

不忿怎么读_不忿

1、“七个不服八个不忿”并不是确数,泛指大家对不合理、不公正的事件和行为的否定态度。2、注音:qīgèbùf

2023-05-16

八一飞行表演队换装歼10C后将首出国门

中国空军新闻发言人谢鹏大校16日公布,按照空军装备建设发展规划,空军八一飞行表演队换装歼-10C飞机,这是

2023-05-16

热消息:百得胜×酷家乐:成功打通前后端,“一体化”订单占比92%

智能在线检测、工艺数字化设计、智能仓储、人机协同作业、质量精准追溯、在线运行监测与故障诊断、产线柔性

2023-05-16

国家统计局:当前中国经济不存在通缩,下阶段也不会出现通缩

国家统计局新闻发言人、国民经济综合统计司司长付凌晖表示,当前价格低位运行主要是阶段性的,当前中国经济

2023-05-16

恒瑞医药涨超4%:公司拟以6亿元-12亿元回购股份 聚看点

截至发稿,报49 60元,涨4 55%。5月16日,恒瑞医药高开,截至发稿,报49 60元,涨4 55%。恒瑞医药昨日晚间

2023-05-16

2023兰马二次抽签中签选手缴费截止!公益名额招募16日开放

2023兰马二次抽签中签选手缴费截止!公益名额招募16日开放  每日甘肃网5月16日讯据兰州晚报报道记者从兰

2023-05-16

5月15日甲醇外盘市场收盘价格波动

CFR东南亚甲醇市场收盘价335 00-337 00美元 吨。美国海湾甲醇市场收盘价86 00-89 00美分 加仑,跌2美分 加

2023-05-16

晨光云海映长城 金山岭壮美如画|全球快讯

初夏时节,小雨过后,位于河北省滦平县的金山岭长城出现壮美的云海景观。古朴的金山岭长城迎着旭日晨光,在

2023-05-16

劢的正确读音是什么?劢是什么意思?

劢的正确读音是什么?劢:mài。《说文解字》:勉力也。《周书》曰:‘用劢,相我邦家。’

2023-05-16

全球快报:昨日V型反转 今日震荡消化(5月16日早评)

早上好!昨天沪指在上午跌近1%的情况下,下午上演“V”型反转,重返3300点上方,沪指涨1 17%报3310 74点,深

2023-05-16

热点在线丨Cemoy21天精华 21包顺序混一起了_cemoy21天精华

1、不是,不是抹上就有明显效果的,需要长时间坚持。2、CEMOY21天极光晚安精华以“光能粒子焕肤”黑科技...

2023-05-16

央行:稳健货币政策要精准有力 总量适度节奏平稳

5月15日,中国人民银行发布《2023年第一季度中国货币政策执行报告》(简称《报告》)表示,稳健的货币政策

2023-05-16

天天新消息丨合同违约金一般按照多少比例收取 合同违约金

今天来聊聊关于合同违约金一般按照多少比例收取,合同违约金的文章,现在就为大家来简单介绍下合同违约金一

2023-05-16

每日速读!斯波:经历一个艰难的赛季重返东决令人振奋 巴特勒准备好了

斯波:经历一个艰难的赛季重返东决令人振奋巴特勒准备好了,斯波,希罗,热火队,雄鹿队,美国篮球,吉米·巴...

2023-05-16

台南空军基地发生意外 一士兵从拖车掉落遭后车碾压身亡

中新网5月15日电据台湾《联合报》等台媒报道,台空军司令部14日深夜表示,所属台南基地陈姓士兵于14日晚执

2023-05-15

【WTA1000罗马站】继李娜、张帅后第三人!郑钦文晋级八强-环球消息

文 羊城晚报全媒体记者龙希北京时间5月15日,WTA1000女子网球巡回赛罗马站继续展开争夺。在女单第四轮的焦

2023-05-15

自我介绍300字初中生 自我介绍300字

今天来聊聊关于自我介绍300字初中生,自我介绍300字的文章,现在就为大家来简单介绍下自我介绍300字初中生

2023-05-15

【世界播资讯】沃尔沃接盘计划落空,江铃汽车八年重卡梦一场

伴随着奔驰卡车国产化的全面落地,尽快实现在中国商用车市场上的本土化运作,是摆在全球商用车巨头们面前最

2023-05-15

当前最新:消息:苹果首批搭载M3芯片的Mac或最早在今年底上市

【环球网科技综合报道】5月15日消息,据外媒报道,苹果首批搭载M3芯片的Mac电脑最早有望在今年年底上市,其

2023-05-15

王笛做客龙华细讲竹枝词:二十四节气是一扇观察鲜活历史的窗口-全球播资讯

在国内外历史学界乃至文学界,国际知名历史学家、澳门大学讲席教授王笛被视为从新文化史、微观史角度研究中

2023-05-15

【世界独家】数说中亚丨哈萨克斯坦:世界上面积最大的内陆国

驼铃声声,丝路绵延。中国与中亚山川相连,是永远分不开的好邻居。古老的丝绸之路见证了中国同中亚交流交往

2023-05-15

今日最新!重庆直飞莫斯科国际航线复航

此次复航,天津航空推出了由国内40余个干支机场始发经重庆中转至莫斯科的联程航班,为中国各地始发至俄罗斯

2023-05-15

每日视点!灾难事故 | 山西连续发生两起高层火灾事故,保险理赔情况不明

5月7日中午12时许,山西省吕梁市临县临泉镇湫河花苑小区发生火情,一单元电缆井内电线着火,造成人员被困。

2023-05-15

招商积余中标广东外语外贸大学、阿里巴巴南湖等多个项目

招商积余成功中标广东外语外贸大学项目、阿里巴巴南湖项目、山东省市场监督管理局项目、京津中关村科技城协

2023-05-15

长沙晟秀园社区举办邻里文化节

新湖南客户端5月15日讯(通迅员程沙张琴)5月13日下午,湖南湘江新区梅溪湖街道晟秀园社区联合辖区各单位举

2023-05-15

利用行业过剩面料再生产 SHEIN携手Queen of Raw创新减废

近日,时尚和生活方式在线零售商SHEIN宣布,与美国可持续时尚企业QueenofRaw建立合作伙伴关系,通过采购其

2023-05-15

最新发布
精彩图文
精彩推送

Copyright @  2015-2018 东方it网版权所有  备案号:沪ICP备2020036824号-8   联系邮箱:562 66 29@qq.com