为什么会有OPTIONS请求
在做项目时,很多时候发送一个post请求,是先发送一个option请求,然后再发送post请求,一直这么用之前也没有仔细思考,今天有时间,好好了解一下为什么会多一次请求。
疑问1:什么是options请求
OPTIONS请求方法的主要用途有两个:
1、获取服务器支持的HTTP请求方法;
2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
这是浏览器给我们加上的,后端并没有做任何操作。
疑问2:为什么会用到options请求
这得从浏览器同源策略和跨域说起,具体可阅读也谈谈同源策略和跨域问题和浏览器同源政策及其规避方法,这里不在赘述。
解决跨域问题的方法有很多种,CORS是比较好的解决方案,我们的项目也是用的这种模式,这个模式会有”预检”的请求,也就是正常请求之前的options请求。
关键词:CORS 跨域资源共享
CORS是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。
通过阅读我们知道,当我们进行跨越请求的时候,因为同源策略的限制,如果访问跨域请求时,跨源资源共享(CORS)机制为web服务器跨域访问控制提供了安全的跨域数据传输。
使用CORS的方式非常简单,但是需要同时对前端和服务器端做相应处理。
1、 前端
客户端使用XmlHttpRequest发起Ajax请求,当前绝大部分浏览器已经支持CORS方式,且主流浏览器均提供了对跨域资源共享的支持。
2、 服务器端
如果服务器端未做任何配置,则前端发起Ajax请求后,会得到CORS Access Deny,即跨域访问被拒绝。
对于C#做如下配置可允许资源的跨域访问:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type" />
<add name="Access-Control-Allow-Methods" value="PUT,GET,POST,DELETE,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>
对于nodejs做如下配置可允许资源的跨域访问:
//设置CORS跨域访问
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");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
Access-Control-Allow-Origin:*表示允许任何域发起请求,如果只允许特定的域访问,则设置Access-Control-Allow-Origin:xxx为具体域名即可。
关键词: Options
OPTIONS请求旨在发送一种“探测”请求以确定针对某个目标地址的请求必须具有怎样的约束(比如应该采用怎样的HTTP方法以及自定义的请求报头),然后根据其约束发送真正的请求。比如针对“跨域资源”的预检(Preflight)请求采用的HTTP方法就是OPTIONS。
简而言之,OPTIONS请求方法的主要用途有两个:
1、获取服务器支持的HTTP请求方法;
2、用来检查服务器的性能。
关键词: Preflighted Requests 预检请求
下面的2种情况需要进行预检:
非简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求;(什么是简单请求,什么是非简单请求,请移步阮一峰的跨域资源共享 CORS 详解)
总结
规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
当请求满足下述任一条件时,即应首先发送预检请求(使用OPTIONS):
1、使用了下面任一 HTTP 方法:
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
2、人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (but note the additional requirements below)
DPR
Downlink
Save-Data
Viewport-Width
Width
3、Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain
为什么会有OPTIONS请求的更多相关文章
- jquery ajax 请求中多出现一次OPTIONS请求及其解决办法
http://www.tangshuang.net/2271.html 在上一篇<服务端php解决jquery ajax跨域请求restful api问题及实践>中,我简单介绍了如何通过服 ...
- ( 转 ) CORS 有一次 OPTIONS 请求的原理
刚接触前端的时候,以为HTTP的Request Method只有GET与POST两种,后来才了解到,原来还有HEAD.PUT.DELETE.OPTIONS-- 目前的工作中,HEAD.PUT.DELE ...
- problem:为什么会有options请求
为了安全考虑,浏览器对资源访问有同源限制的问题,也就是web应用程序只能访问和它同一协议同一域名同一端口的web应用程序上的资源. 通过跨域资源共享机制可以让资源在浏览器中访问与该资源本身不同域的资源 ...
- http跨域时的options请求
1.背景 在前后端分离的项目中经常会遇到跨域请求的问题,如果没有进行跨域配置,会浏览器请求失败.我一般采用两种解决方案: 1.采用nginx进行转发,是前后端服务处于同一个域下面,从根本上避免跨域问题 ...
- Laravel 处理 Options 请求的原理以及批处理方案
0. 背景 在前后端分离的应用中,需要使用CORS完成跨域访问.在CORS中发送非简单请求时,前端会发一个请求方式为OPTIONS的预请求,前端只有收到服务器对这个OPTIONS请求的正确响应,才会发 ...
- Laravel + Vue 之 OPTIONS 请求的处理
问题: 在 Vue 对后台的请求中,一般采用 axios 对后台进行 Ajax 交互. 交互发生时,axios 一般会发起两次请求,一次为 Options 试探请求,一次为正式请求. 由此带来的问题是 ...
- AJAX 请求中多出了一次 OPTIONS 请求 导致 Laravel 中间件无法对 Header 传入的 Token 无法获取
背景知识: 我们会发现,在很多post,put,delete等请求之前,会有一次options请求.本文主要是来讨论一下这是什么原因引起的. 根本原因就是,W3C规范这样要求了!在跨域请求中,分为简单 ...
- AJAX请求中出现OPTIONS请求
背景 有一个前后端分离的VUE项目来发送ajax请求, 查看Nginx日志或使用Chrome Dev Tools查看请求发送情况时, 会看到每次调后台API的请求之前, 都会发送一个OPTIONS请求 ...
- Spring boot处理OPTIONS请求
一.现象从fetch说起,用fetch构造一个POST请求. fetch('http://127.0.0.1:8000/api/login', { method: "POST", ...
随机推荐
- [UWP]了解TypeConverter
1. 前言 TypeConverter是XAML解释器的幕后功臣,它做了大量工作,从WPF诞生以来,几乎每一次XAML的运作都有它的参与.虽然UWP中TypeConverter已经彻彻底底退居幕后,连 ...
- mango(mango ORM框架介绍)
官网地址:http://www.jfaster.org/ mango的中文名是"芒果",它是一个极速分布式ORM框架.目前已有十多个大型线上项目在使用mango,在某一支付系统中, ...
- 引号在jsp页面中正确显示的处理
写在前面: 在前面的博客中已经有了对一些特殊字符的处理,但是万万没有想到,出来了一个含有引号的字符串,比如这样的ab"c"d的一个字符串.如果在超链接传值的时候,会与前面的引号成对 ...
- C# 委托高级应用----线程——创建无阻塞的异步调用(一)
前言 本文大部分内容来自于mikeperetz的Asynchronous Method Invocation及本人的一些个人体会所得,希望对你有所帮助.原英文文献可以在codeproject中搜索到. ...
- 【java设计模式】【行为模式Behavioral Pattern】策略模式Strategy Pattern
package com.tn.策略模式; public class Client { private Strategy strategy; public void setStrategy(Strate ...
- Vue.js(一)了解Vue
什么是Vue? 1.Vue.js是一个构建数据驱动的web界面的库.类似于Angularjs,在技术上,他重点集中在MVVM模式的View层,非常容易学习,非常容易和其他的库或已有的项目整合. 2.V ...
- Java之数据类型,变量赋值
Java中的基础数据类型(四类八种): 1.整数型 byte----使用byte关键字来定义byte型变量,可以一次定义多个变量并对其进行赋值,也可以不进行赋值.byte型是整型中所分配的内存空间是最 ...
- UILabletext去掉乱码 控制颜色 行高 自定义大小 。显示不同的字体颜色、字体大小、行间距、首行缩进、下划线等属性(NSMutableAttributedString)
text去掉乱码 设置不同颜色 行高 自定义大小 #import <Foundation/Foundation.h> @interface TextsForRow : NSObject @ ...
- boost::format(字符串格式化库)
这段时间学习boost库的使用,撰文一方面留以备用,另一方面就是shared精神. format主要是用来格式化std::string字符串以及配合std::cout代替C语言printf() 使用f ...
- Wincc的使用
1.组态项目步骤 1)启动Wincc 2)建立项目 3)选择及安装通信驱动程序 4)定义变量 5)建立和编辑过程画面 6)指定Wincc运行系统的属性 7)激活Wincc画面 8)使用变量模拟器测试过 ...