引自:https://www.jianshu.com/p/5cf82f092201、https://www.cnblogs.com/mamimi/p/10602722.html

一、options是什么

​ http的请求方式,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT等八种请求方式。其中,get与post只是我们最常用的请求方式。

options请求的官方定义:OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。

也说就是:在发生正式的请求之前,先进行一次预检请求。看服务端返回一些信息,浏览器拿到之后,看后台是否允许进行访问。

二、为什么会产生options请求

原因:

  1. 客户端发送了复杂请求。复杂请求对应简单请求。
  2. 客户端的请求跨域。

简单请求:

  1. 请求方法只能是GET或HEAD或者POST。
  2. 当请求方法是POST时,Content-Type必须是application/x-www-form-urlencoded、multipart/form-data、text/plain中的一个值。
  3. 请求头没有自定义HTTP头部。请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID。

三、options请求的作用

官方将头部带自定义信息的请求方式称为带预检(preflighted)的跨域请求。在实际调用接口之前,会首先发出一个options请求,检测服务端是否支持真实的请求进行跨域的请求。真实请求在options请求中,通过request-header将 Access-Control-Request-Headers与Access-Control-Request-Method发送给后台,另外浏览器会自行加上一个Origin请求地址。服务端在接收到预检请求后,根据资源权限配置,在response-header头部加入access-control-allow-headers(允许跨域请求的请求头)、access-control-allow-methods(允许跨域请求的请求方式)、access-control-allow-origin(允许跨域请求的域)。另外,服务端还可以通过Access-Control-Max-Age来设置一定时间内无须再进行预检请求,直接用之前的预检请求的协商结果即可。浏览器再根据服务端返回的信息,进行决定是否再进行真实的跨域请求。这个过程对于用户来说,也是透明的。

另外在HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allow-Credentials: true的,浏览器都会忽略此次响应。

总结:只要是带自定义header的跨域请求,在发送真实请求前都会先发送OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。所以复杂请求肯定会两次请求服务端。也就是说,浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,服务器允许之后,浏览器才会发出正式的XMLHttpRequest请求,否则会报错。

四、options请求如何避免

  1. 使用代理,避开跨域。
  2. 将复杂跨域请求更改为简单跨域请求。
  3. 不使用带自定义配置的header头部。
  4. 后端解决,设置不进行options预检。

Http中的options请求的更多相关文章

  1. AJAX请求中出现OPTIONS请求

    背景 有一个前后端分离的VUE项目来发送ajax请求, 查看Nginx日志或使用Chrome Dev Tools查看请求发送情况时, 会看到每次调后台API的请求之前, 都会发送一个OPTIONS请求 ...

  2. 服务网关ZuulFilter过滤器--如何解决跨域请求中的OPTIONS请求

    进行跨域请求的时候,并且请求头中有额外参数,比如token,客户端会先发送一个OPTIONS请求 来探测后续需要发起的跨域POST请求是否安全可接受 所以这个请求就不需要拦截,下面是处理方式 @Ove ...

  3. jquery ajax 请求中多出现一次OPTIONS请求及其解决办法

    http://www.tangshuang.net/2271.html 在上一篇<服务端php解决jquery ajax跨域请求restful api问题及实践>中,我简单介绍了如何通过服 ...

  4. AJAX 请求中多出了一次 OPTIONS 请求 导致 Laravel 中间件无法对 Header 传入的 Token 无法获取

    背景知识: 我们会发现,在很多post,put,delete等请求之前,会有一次options请求.本文主要是来讨论一下这是什么原因引起的. 根本原因就是,W3C规范这样要求了!在跨域请求中,分为简单 ...

  5. webapi处理OPTIONS请求

    报错1信息 Access to XMLHttpRequest at 'http://localhost:4445/api/v/getmsg' from origin 'http://localhost ...

  6. SpringCloud+ZUUL跨域请求中的OPTIONS请求处理

    目前项目结构是VUE做前端,后端采用微服务架构,在开发时前端需要跨域请求数据,通过CorsConfig配置解决了简单跨域请求需要.但当需要在请求的header中增加token信息时,出现了请求失败的情 ...

  7. 跨域请求中预检请求options之坑

    一.前言 因为跨域请求,浏览器可能(后面讲)会发送一次options请求,如果处理不好,跨域还是会gg的. 之前很少涉及跨域,涉及也是简单请求(下面阮老师文章中区别热简单请求和复杂请求),所以基本不会 ...

  8. "Chrome的network中无法显示OPTIONS请求"的解决方案

    目录 #事故现场 #分析及解决方法 #参考 #事故现场 在前端发送一个跨域请求的时候,要先发送个options请求,从而获知服务端是否允许该跨域请求. 跨域资源共享标准新增了一组 HTTP 首部字段, ...

  9. nginx过滤access_log中HEAD、OPTIONS请求记录

    网上很多教程说是这样做: if ($request_method = HEAD) { access_log off; } 试了之后是不行的,正确的做法如下: http { map $request_m ...

随机推荐

  1. 机器学习速查表(cheatsheet)资源汇总分享

    本文收集整理了机器学习相关速查表(Machine Learning Cheatsheet),包含机器学习.Python.Numpy.Pandas.Matplotlib.线性代数.微积分.统计学.概率论 ...

  2. DirectX 11的初始化

    总体来说可以概括为以下几个步骤: 创建Device和Context 创建SwapChain 为BackBuffer创建View 创建Depth/Stencil Buffer,并为之创建View 将Vi ...

  3. burp中获取token进行暴力破解

    选中线程设成1

  4. 前端Firebug常见错误:SyntaxError:missing variable nam

    出现上面那个问题应该是 某个地方,分号写错了 检查一下是否由于应该写分号的地方写成了其他符号.

  5. Sharding-JDBC使用jasypt3.0及以上版本加密数据库连接密码

    本文中介绍的是基于Sharding-JDBC 4.0和jasypt 3.0及其以上版本对数据库连接密码进行加密操作 引入依赖 项目的pom.xml中引入maven依赖 <dependency&g ...

  6. iOS UIcollectionView 实现卡牌翻转效果

    - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...

  7. HCIP --- BGP 总结

    AS:自治系统  --逻辑管理域(例如移动.电信.联通),AS号范围:0-65535,其中,1-64511:公有AS,64512-65535:私有AS IGP:内部网关协议,在一个AS之内传递的路由协 ...

  8. 【命令】set命令

    1.查看所有的本地变量和环境变量. 2.检测变量是否定义: 开启检测功能: set -u  关闭检测功能:   set +u [root@localhost likui]# unset mm 删除了m ...

  9. 基于nginx负载均衡及frp的内网穿透实例3-多用户多网站共用80端口

    原文地址:点击跳转 最近frp用户量有点多,而且很多用户都是想把部署于本地或者内网的web服务暴露至公网,之前提到过,暴露到公网之后如果一般都需要用域名:端口的方法来访问,但是没有人会喜欢用这种方式访 ...

  10. @Transient 注解

    使用 @Transient 表示该属性并非是一个要映射到数据库表中的字段,只是起辅助作用.ORM框架将会忽略该属性