-
2019-10-18 11:37:22
在项目开发 使用axios进行数据请求时,发现同一个接口会被请求两次,一个requirtMethods是option ,一个是,正常的get/post请求,返回200请求成功。
那么OPTIONS 这个请求是什么呢,我们不妨来了解一下。
---------------------------------
Preflighted Requests(预检请求)
Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。
什么是CORS?
这是CDN对于CROS的解释 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
更多相关内容 -
关于option请求
2021-02-11 17:27:48OPTION请求是浏览器为确定跨域请求资源的安全做的预请求,解决OPTION请求有两种方式第一种是使用简单请求,第二种是设置浏览器预校验请求失效时间。 案例引入 模仿登录请求写了一个简单的案例,下面给出会发送...爱总结,爱搬砖,爱生活
引言
前不久用
Vue
和node
搭建个人博客,用Axios
做网络请求,在做博主登录验证的时候总是会发送两条相同的请求,其中一条的请求方式为OPTION
,然后看了几篇博客,基本提到的是跨域、浏览器预校验、简单请求、复杂请求,下面围绕OPTION
总结一下。心得
OPTION
请求是浏览器为确定跨域请求资源的安全做的预请求,解决OPTION
请求有两种方式第一种是使用简单请求,第二种是设置浏览器预校验请求失效时间。案例引入
- 模仿登录请求写了一个简单的案例,下面给出会发送
OPTION
请求的代码(极简单的案例只为突出解决OPTION请求的问题,其他问题不是本篇博客的范畴)
node代码
const express = require('express') const jwt = require('jsonwebtoken'); const app = express() const port = 3000 // 解决跨域问题 app.all('*', function (req, res, next) { res.header("Access-Control-Allow-Origin", "*") res.header("Access-Control-Allow-Headers", "X-Requested-With, accept, origin, content-type, Authorization") res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS") res.header("X-Powered-By", ' 3.2.1') next() }) app.get('/', (req, res) => { const token = jwt.sign({ foo: 'bar' }, 'shhhhh') res.send(token) }) app.post('/login', (req, res) => { const token = req.headers.authorization let result jwt.verify(token, 'shhhhh', function(err, decoded) { if (err) { console.log(err); res.send(500) } else { result = 'success' res.send(result) } }); }) app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
Vue代码
<template> <div id="app"> <button @click="login">点击</button> </div> </template> <script> import axios from 'axios' export default { name: 'App', data(){ return { token: '' } }, mounted() { axios.get('http://localhost:3000/').then(data => { this.token = data.data }) }, methods: { login() { axios.request({ url: 'http://localhost:3000/login', method: 'post', headers: { 'Authorization': this.token } }).then(data => { console.log(data); }) } } } </script> <style scoped> </style>
- 上面的代码在执行
login
事件函数时每次都会向服务器发送两次同样的请求,其中一次就是本篇博客的主角OPTION
请求,接下来是针对OPTION
请求的一番探究。
什么时OPTION请求
- 跨域请求资源时浏览器为确认请求来源的安全性,会在正式的请求之前做一次预校验请求,待服务器允许之后才能发送正式的请求,这个预校验请求就是
OPTION
请求; - 并不是每次跨域资源请求都会发送
OPTION
请求,当跨域请求为简单请求的时就不会发送预校验请求,当跨域请求为复杂请求时才会发送预校验请求; - 跨域请求就不再做详细的阐述,来看一下什么是简单请求和复杂请求。
简单请求和复杂请求
- 先看什么是简单请求,不满足简单请求的就是复杂请求
- 有些请求不会触发CORS的预检。尽管Fetch规范(定义了 CORS)没有使用该术语,但在本文中将这些称为“简单请求”。“简单请求”是满足以下所有条件的请求:
允许的方法之一:- GET
- HEAD
- POST
- WSS除了由用户代理自动设置的标头(例如,Connection,User-Agent,或在定义的其它标题抓取规格为“禁止的标题名称”),其允许被手动设置仅标头是那些抓取规范定义为“ CORS安全列出的请求标头”,它们是:
- Accept
- Accept-Language
- Content-Language
- Content-Type (但请注意下面的其他要求)
- Content-Type标头唯一允许的值为:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- 没有在事件中使用的任何XMLHttpRequest.upload对象上注册事件侦听器;使用XMLHttpRequest.upload属性访问这些。
- ReadableStream请求中未使用任何对象。
- 上面这段内容摘自CND跨域资源共享(CORS),这篇文章值得多读几遍;
- 对比简单请求,可想而知什么是复杂请求;
- 回过头去看一下博客开头的引入案例,在登录请求中将token携带在请求头中,显然这个请求不再是跨域简单请求,因此在正式的登录请求之前会发送
OPTION
请求,获得‘批准’之后才会发送正式的登录请求;
OPTION请求好吗?
OPTION
请求是浏览器的一种安全策略,当然好,但是过多的OPTION
请求会占用浏览器的资源,影响页面的性能,所以要尽可能的减少OPTION
请求。怎么解决OPTION请求的问题
- 解决
OPTION
请求有两条思路- 不使用复杂请求
- 给浏览器的预校验设置失效时间
OPTION
请求只有在跨域复杂请求的时候才会有,所以就有了第一种解决思路,不要使用复杂请求,取而代之的是使用简单请求;- 第二种思路是给浏览器设置预校验失效时间,通过在服务端设置请求头
Access-Control-Max-Age
,下面贴出具体的代码;
node代码
// 解决跨域问题 app.all('*', function (req, res, next) { res.header("Access-Control-Allow-Origin", "*") res.header("Access-Control-Allow-Headers", "X-Requested-With, accept, origin, content-type, Authorization") res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS") // 下面代码设值了浏览器预校验请求的失效时间为60s res.header("Access-Control-Max-Age", 60) res.header("X-Powered-By", ' 3.2.1') next() })
爱总结,爱搬砖,爱生活
- 模仿登录请求写了一个简单的案例,下面给出会发送
-
跨域中option请求详解
2021-09-09 14:59:20跨域中option请求详解 在正式跨域的请求前,浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域),还有是否需要...跨域中option请求详解
在正式跨域的请求前,浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域),还有是否需要Credentials(认证信息)三种场景:
- 如果跨域的请求是Simple Request(简单请求 ),则不会触发“PreFlight”。Mozilla对于简单请求的要求是:
以下三项必须都成立: - 只能是Get、Head、Post方法
- 除了浏览器自己在Http头上加的信息(如Connection、User-Agent),开发者只能加这几个:Accept、Accept-Language、Content-Type、。。。。
- Content-Type只能取这几个值:
application/x-www-form-urlencoded
multipart/form-data
text/plain
一、为什么会出现options请求呢?
跨域请求中,options请求是浏览器自发起的preflight request(预检请求),以检测实际请求是否可以被浏览器接受。
preflight request请求报文中有两个需要关注的首部字段:
(1)Access-Control-Request-Method:告知服务器实际请求所使用的HTTP方法;
(2)Access-Control-Request-Headers:告知服务器实际请求所携带的自定义首部字段。
同时服务器也会添加origin header,告知服务器实际请求的客户端的地址。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
服务器所返回的Access-Control-Allow-Methods首部字段将所有允许的请求方法告知客户端,返回将所有Access-Control-Request-Headers首部字段将所有允许的自定义首部字段告知客户端。此外,服务器端可返回Access-Control-Max-Age首部字段,允许浏览器在指定时间内,无需再发送预检请求,直接用本次结果即可。
在我们开发过程中出现的浏览器自发起的options请求就是上面的第二种情况。实际上,跨域请求中的”复杂请求”发出前会进行一次方法是options的preflight request。
二、当跨域请求是简单请求时不会进行preflight request,只有复杂请求才会进行preflight request。
跨域请求分两种:简单请求、复杂请求;
符合以下任一情况的就是复杂请求:
1.使用方法put或者delete;
2.发送json格式的数据(content-type: application/json)
3.请求中带有自定义头部;
除了满足以上条件的复杂请求其他的就是简单请求喽!
三、为什么跨域的复杂请求需要preflight request?
复杂请求可能对服务器数据产生副作用。例如delete或者put,都会对服务器数据进行修改,所以在请求之前都要先询问服务器,当前网页所在域名是否在服务器的许可名单中,服务器允许后,浏览器才会发出正式的请求,否则不发送正式请求。
- 如果跨域的请求是Simple Request(简单请求 ),则不会触发“PreFlight”。Mozilla对于简单请求的要求是:
-
axios 发送 option 请求问题
2021-06-20 01:43:05如果请求 method 的是 option 会导致 HttpServletRequest 读取不到请求内容。 axios 的 option 请求目的是确认后端服务是否允许跨站请求,因此后端这边特殊处理一下 option 请求即可 在 filter 中如果遇到 option ...后端服务框架 SpringBoot
如果请求 method 的是 option 会导致 HttpServletRequest 读取不到请求内容。
axios 的 option 请求目的是确认后端服务是否允许跨站请求,因此后端这边特殊处理一下
option 请求即可在 filter 中如果遇到 option 请求直接返回
public class SecretFilter extends OncePerRequestFilter { String defaultRsp = "{}"; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { boolean secret = String.valueOf(1).equals(request.getHeader("fu-secret")); if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.getOutputStream().write(defaultRsp.getBytes(StandardCharsets.UTF_8)); response.setStatus(HttpStatus.OK.value()); response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE"); response.setHeader("Access-Control-Allow-Headers", "*"); return; } String body = IoUtil.readString(request.getInputStream()); try { filterChain.doFilter(new FuminoRequestWrapper(request, body), response); } finally { response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization,Content-Type"); } }
-
option请求解决跨域问题
2020-09-16 18:59:46前端请求是连续发送两次请求,第一次option请求返回200,未携带参数,第二次请求get携带参数,未成功 两次请求统一接口 这里问题产生原因和vue设置代理无关 需要后台解决 我尝试了2中解决方法,都可以 1. ... -
跨域访问拦截器——OPTION请求
2020-04-01 18:55:10Springboot跨域访问为什么会出现OPTION请求呢? ** 请求方式有两大类,一类是简单的请求,一类是非简单的请求。简单的请求类似于GET、POST、HEAD等,非简单的请求如PUT、DELETE等。对于简单请求,浏览器直接发本次... -
前后端分离跨域问题之OPTION请求
2020-08-09 14:39:59在正式跨域的请求前,浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源,或者域),还有是否需要Credentials(认证信息) ... -
Bug post/get请求 响应的是 option请求,看不到请求参数和返回值
2021-02-05 16:21:24前端发的post请求、get请求,请求成功,页面的数据也能渲染出来,但是network那里响应的是option请求,看不到请求的参数,看不到返回的结果 解决 一些浏览器不支持自定义请求头header,或者需要其它设置,换成谷歌... -
跨域,发送post请求带jwt时,多发一个option请求
2020-11-17 19:56:03跨域在发送带jwt的post请求时,会先发送一个option的请求,所以在jwt过滤器中,需要先将options请求放掉 if (req.getMethod().equalsIgnoreCase("OPTIONS")) { //跨域发送复杂请求(post)首先发送OPTIONS请求 return... -
浏览器发送option请求成功后不发送post请求
2019-12-19 15:55:20浏览器发送option请求成功后不发送get/post请求,浏览器报错 Request header field xfilesize is not allowed by Access-Control-Allow-Headers 原因 跨域请求中,options请求是浏览器自发起的preflight request... -
js:get/post/put/delete/option请求
2021-01-08 16:47:29get请求会把请求的参数附加在URL后面,这样会产生安全问题,如果是系统的登陆接口采用的get请求,需要对请求的参数做一个加密。 get请求其实本身HTTP协议并没有限制它的URL大小,但是不同的浏览器对其有不同的大小... -
解决Charles映射本地时option请求的跨域问题
2021-05-19 16:32:46问题: 用Charles的Map Local映射接口后,option请求少了Response Headers,导致跨域报错了 解决: 使用Charles的rewrite添加需要的Response Headers 1.从映射前的option接口中获取需要添加的Response Headers内容 ... -
关于springMVC拦截器拦截option请求的问题
2019-10-24 13:15:26前台访问后台,会带option请求。 后台的拦截器若将option请求进行权限拦截,真正的请求就不进行发送 所以后台需要对option请求放行。 在拦截器里,调用这个方法,能获得这次拦截的方法类型。 request.... -
Spring Boot配置跨域后PUT和DELETE请求自动变成OPTION请求的解决方案
2020-03-03 22:17:14Spring Boot配置跨域后PUT和DELETE请求自动变成OPTION请求的解决方案 在配置前后端分离的项目时,前端和后端都需要对数据跨域做相应的处理 Spring Boot可以通过配置的方式进行处理,重写WebMvcConfigurer 的 ... -
解决axios会发送两次请求,有个OPTIONS请求的问题
2021-01-19 19:21:14原因是:浏览器会首先使用 OPTIONS 方法发起一个预请求,判断接口是否能够正常通讯,如果不能就不会发送真正的请求过来,如果测试通讯正常,则开始真正的请求。 大概意思就是: 浏览器对后台说:我可以请求你吗? ... -
option请求与跨域
2019-12-04 18:46:15以前也知道HTTP请求中有option方法,只是大概知道是用来询问服务器支持什么请求方法的,直到今天遇到了一个很奇怪的问题,才对option方法有更深一步的理解。 前提:项目是vue+django,我把前端项目运行起来,使用... -
跨域ajax阻止option请求
2018-04-10 09:54:10直接上代码beforeSend: function(xhr) { try { xhr.withCredentials = true; } catch (e) { var nativeOpen = xhr.open; ... -
OPTION请求报400——CORS跨域请求
2020-01-17 10:53:06原文链接 跨域请求 CORS即Cross Origin Resource Sharing(跨来源资源共享),通俗说就是我们所熟知的跨域请求。众所周知,在以前,跨域可以采用代理、JSONP等方式,而在Modern浏览器面前,这些终将成为过去式,因为... -
CORS的option请求发的出去吗
2017-03-07 08:53:38同源策略,对浏览器和服务器都有限制。 CORS,跨域的时候,先发一个option请求,去探测服务器是否允许访问。可是option请求本身也是发不出去的吧,按照现在浏览器的机制。 -
post 变成option 请求的三种原因以及解决办法
2020-06-20 16:22:24简而言之,OPTIONS请求方法的主要用途有两个: 获取服务器支持的HTTP请求方法; 用来检查服务器的性能。 2.CORS(跨域资源共享) CORS是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从... -
head和option请求方式
2020-12-25 17:50:45head和get方式是一样的,但是只是响应中只有响应头,没有返回数据 option方法,是一种“试探连接”(ping操作),并且放回当前url可以请求的方式(get,post等) -
请求方法之Option
2019-02-26 18:10:09简单来说就是发送 OPTION请求询问服务器,你支持哪种请求方法啊? 支持GET,POST和OPTION 如图:响应头参数中Allow,表示服务器允许的请求方法 常见使用情况: 在使用CORS跨域时,前端请求后端服务器时会先发一个... -
为什么HTTP请求的时候会出现一次option的请求?看这里的解释
2019-06-20 22:56:02上图是一个请求的整个过程,然后我们可以看到,其中有一个是我们经常看到的问题,就是option 的预请求,那么图中并没有说明什么是简单的请求,所以下面的链接是解释了什么是简单的请求,也就是一个简单的请求的标准... -
关于浏览器的预检(OPTION)请求
2022-01-26 10:18:41OPTION请求没有附带请求数据,响应体也为空 1. OPTION预检请求的作用 OPTION请求用于获取目的资源所支持的通信选项 检测服务器所支持的请求方法 CORS中的预检请求 CORS规范要求,对那些可能对服务器数据产生副作用... -
options请求
2022-01-09 22:28:53一个Option请求引发的深度解析 在当前项目中,前端通过POST方式访问后端的REST接口时,发现两条请求记录,一条请求的Request Method为Options,另一条请求的Reuest Method为Post。想要解决这个疑惑还得从以下3个概念... -
前端请求接口浏览器发起option预请求而导致405的问题
2019-07-22 12:11:51记一次前端请求后端接口出现405的问题: 问题描述: 首先阐述http的405状态码,405的直接提示是method not allowed,即前端请求的方法不被后端接受。(如下图) 当时就纳闷了,我后端路由明明写的post方法,... -
HTTP请求OPTION方法
2020-08-14 12:47:25OPTIONS请求方法的主要用途有两个: 1、获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。 2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头... -
前端每次请求数据时,都会先发一个option的请求请求,然后才有post, 这种是什么情况该怎么爬取?
2020-12-23 18:28:07这个情况叫做跨域,如果你是后台爬这个东西,正常发请求就OK,就只CORS机制本身来讲是不会限制后台请求的。(当然如果服务器强限制Origin或者包含其它校验逻辑的话就另说了)我们下面大概说一下这种跨域方案的实现机制... -
解决在vue中使用axios,发送请求会发送option空请求的问题
2019-11-02 13:14:501.先让我们来看看为什么浏览器会多发送一个空的option请求呢 因为浏览器在某些请求中,在正式通信前会增加一次HTTP查询请求,称为"预检"请求(preflight) 浏览器先询问服务器,当前网页所在的域名是否在服务器的... -
http跨域时的options请求
2021-03-21 08:37:41其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源或者域),还有是否需要Credentials(认证信息)等。那么浏览器在什么情况下...