options请求

<1>

一个Option请求引发的深度解析

在当前项目中,前端通过POST方式访问后端的REST接口时,发现两条请求记录,一条请求的Request Method为Options,另一条请求的Reuest Method为Post。想要解决这个疑惑还得从以下3个概念说起。

Http Options Method

RFC2616标准(现行的HTTP/1.1)中如下描述:

img

简而言之,OPTIONS请求方法的主要用途有两个:

1、获取服务器支持的HTTP请求方法;

2、用来检查服务器的性能。

CORS(跨域资源共享)

CORS是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。

使用CORS的方式非常简单,但是需要同时对前端和服务器端做相应处理。

1、 前端

客户端使用XmlHttpRequest发起Ajax请求,当前绝大部分浏览器已经支持CORS方式,且主流浏览器均提供了对跨域资源共享的支持。

2、 服务器端

如果服务器端未做任何配置,则前端发起Ajax请求后,会得到CORS Access Deny,即跨域访问被拒绝。

对于C#做如下配置可允许资源的跨域访问:

<system.webServer>








</system.webServer>

对于nodejs做如下配置可允许资源的跨域访问:

//设置CORS跨域访问
app.all(’’, function (req, res, next) {undefined
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为具体域名即可。

Preflighted Requests(预检请求)

Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。

下面的2种情况需要进行预检:

1、 简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求;

2、中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等。

img

了解完这3个概念,其实答案已经了然了。

参考:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

http://blog.csdn.net/hfahe/article/details/7730944

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

<2>

HTTP请求方法并不是只有GET和POST,只是最常用的。据RFC2616标准(现行的HTTP/1.1)得知,通常有以下8种方法:OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT。

HTTP请求方法并不是只有GET和POST,只是最常用的。据RFC2616标准(现行的HTTP/1.1)得知,通常有以下8种方法:OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT。

官方定义

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

该请求方法的响应不能缓存。

如果这个OPTIONS请求包含一个正文(有Content-Length或Transfer-Encoding存在),则必须有Content-Type来指定媒体类型。虽然规范里没有定义这种正文的用法,但是HTTP将来的扩展可能会用它来查询服务器上更详细的信息。不支持该扩展的服务器可以忽略该请求正文。

如果该URI是一个星号(“”),OPTIONS请求将试图应用于服务器,而不是某个指定资源。由于服务器的通信选项通常依赖于资源,所以此“”请求只能作为“ping”或者“no-op”方法;或者用来测试服务器的性能。例如,用来测试HTTP/1.1代理。

如果该URI不是星号,则只能用来获取该资源通信中可用的选项。

得到的200响应应该包含一个头域,指明服务器实现的和适用于该资源的可选特征(如:Allow),可能还包括该规范尚未定义的扩展。如果有响应正文,则应包含关于通信选项的信息。本规范没有定义该正文格式,但可能在HTTO将来的扩展中定义。可以利用内容协商来选择合适的响应格式。如果没有响应正文,响应必须包含Content-Length,并且值为“0”。

请求头的Max-Forwards用来请求特定代理。当代理收到一个允许URI转发的OPTIONS请求,则检查Max-Forwards。如果Max-Forwards值为0,则不能转发该消息;相反,代理会将自己的通信选项去响应。如果Max-Forwards是正整数,代理转发请求的时候会将该值减1。如果请求中没有Max-Forwards,转发的请求也不会有。

简而言之

OPTIONS请求方法的主要用途有两个:

1、获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。

2、用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。

The DELETE Method

HTTP提供了一个与PUT方法对应的DELETE方法。一个DELETE请求将需要从Web服务器删除的内容指定为请求行中的资源部分。
DELETE方法唯一有趣的地方在于当你接收了一个标识为200 OK的响应的时候,那并不意味着指定的资源已经被删除了。那仅仅说明服务器接收到了删除资源的命令。这一例外允许了出于安全考虑的人为的干预

转自:http://blog.csdn.net/leikezhu1981/article/details/7402272

<3>

出于安全考虑,并不是所有域名访问后端服务都可以。其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源或者域),还有是否需要Credentials(认证信息)等。那么浏览器在什么情况下能预检呢?

二、两种请求方式

浏览器将CORS请求分为两类:简单请求(simple request)和非简单请求(not-simple-request),简单请求浏览器不会预检,而非简单请求会预检。这两种方式怎么区分?

同时满足下列三大条件,就属于简单请求,否则属于非简单请求

1.请求方式只能是:GET、POST、HEAD

2.HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID

3.Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain

对于简单请求,浏览器直接请求,会在请求头信息中,增加一个origin字段,来说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值,来决定是否同意该请求,服务器返回的响应会多几个头信息字段,如图所示:上面的头信息中,三个与CORS请求相关,都是以Access-Control-开头。

1.Access-Control-Allow-Origin:该字段是必须的,* 表示接受任意域名的请求,还可以指定域名

2.Access-Control-Allow-Credentials:该字段可选,是个布尔值,表示是否可以携带cookie,(注意:如果Access-Control-Allow-Origin字段设置*,此字段设为true无效)

3.Access-Control-Allow-Headers:该字段可选,里面可以获取Cache-Control、Content-Type、Expires等,如果想要拿到其他字段,就可以在这个字段中指定。比如图中指定的GUAZISSO

非简单请求是对那种对服务器有特殊要求的请求,比如请求方式是PUT或者DELETE,或者Content-Type字段类型是application/json。都会在正式通信之前,增加一次HTTP请求,称之为预检。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,服务器允许之后,浏览器会发出正式的XMLHttpRequest请求,否则会报错。(备注:之前碰到预检请求后端没有通过,就不会发正式请求,然后找了好久原因,原来后端给忘了设置…)Java后端实现拦截器,排除Options

img

JAVA代码片段

就Content-Type为application/json为例:对比两张图片,一次预检请求,一 次正式请求:

img

预检请求

img

正式请求

很明显,请求头中预检请求不会携带cookie,正式请求会携带cookie和参数。跟普通请求一样,响应头也会增加同样字段。

一旦服务器通过了“预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555934.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线程中可以创建进程吗_Linux 进程线程是如何创建的?

上文讲了《Linux进程在内核眼中是什么样子的&#xff1f;》&#xff0c;可以理解内核关于进程线程的所有管理就通过一个结构体 —— task_struct。知道了内核眼中进程的描述&#xff0c;本文通过三个例子站在用户态看下进程线程是如何创建的&#xff0c;不同的创建方式又有哪些…

http请求发生了两次(options请求)

前言 自后台restful接口流行开来&#xff0c;请求了两次的情况&#xff08;options请求&#xff09;越来越普遍。笔者也在实际的项目中遇到过这种情况&#xff0c;做一下整理总结。 文章书写思路&#xff1a; 为什么发生两次请求 http的请求方式&#xff0c;包括OPTIONS、GET…

servlet怎么接受请求_谁再问Servlet的问题,我就亲自上门来教学了

1. 概述在这篇简短的文章中&#xff0c;我们将从概念上理解什么是servlet 和 servlet 容器以及它们是如何工作的。同时&#xff0c;还能在请求、响应、会话对象、共享变量和多线程的上下文中看到它们的身影。2. Servlets 和 它的容器servlet 是 JEE 用于 web 开发常用的组件。它…

Mysql中SQL语句不使用索引的情况

Mysql中SQL语句不使用索引的情况 MySQL查询不使用索引汇总 众所周知&#xff0c;增加索引是提高查询速度的有效途径&#xff0c;但是很多时候&#xff0c;即使增加了索引&#xff0c;查询仍然不使用索引&#xff0c;这种情况严重影响性能&#xff0c;这里就简单总结几条MySQL…

详解mysql什么时候不走索引

全值匹配我最爱&#xff0c;最左前缀要遵守&#xff1b; 带头大哥不能死&#xff0c;中间兄弟不能断&#xff1b; 索引列上不计算&#xff0c;范围之后全失效&#xff1b; LIKE百分写最右&#xff0c;覆盖索引不写 *&#xff1b; 不等空值还有or&#xff0c;索引失效要少用&…

unbuntu cmake安装mysql_ubuntu下编译安装mysql5.5

1.主要步骤如下添加mysql用户和用户组—>下载源码—>解压源码安装编译2个套件—>编译源码-安装编译好的程序-配置mysql启动服务2.Mysql源码解压建好相应的安装目录&#xff0c;将压缩文件复制到安装目录并解压。3.添加用户组Sudo groupadd mysql4.添加用户Sudo userad…

mysql删库后恢复_记一次MySQL删库的数据恢复

昨天因为不可描述的原因&#xff0c;数据库直接被 drop database删除。在第一时间停止数据库服务和Web服务&#xff0c;备份MySQL数据目录下的所有文件之后&#xff0c;开始走上数据恢复之路。第一次干这种事&#xff0c;各种不得法。因为我们既没有备份&#xff0c;也没有开启…

Mysql 中的Text字段的范围

Mysql 中的Text字段的范围 text&#xff1a;存储可变长度的非Unicode数据&#xff0c;最大长度为2^31-1个字符。text列不能有默认值&#xff0c;存储或检索过程中&#xff0c;不存在大小写转换&#xff0c;后面如果指定长度&#xff0c;不会报错误&#xff0c;但是这个长度是不…

python实现语义分割_语义分割算法之FCN论文阅读及源码实现

论文原文创新点提出了一种端到端的做语义分割的方法&#xff0c;在这里插入图片描述如图&#xff0c;直接拿分割的ground truth作为监督信息&#xff0c;训练一个端到端的网络&#xff0c;让网络做p像素级别的预测。如何设计网络结构如何做像素级别的预测在这里插入图片描述在V…

右上角的引用文献格式_论文要引用的小符号右上角怎么打?

上标是【现在】论【文的】书写【都会】【用到】引用【的小】符号&#xff0c;上标【一般】用【来对】所标的【文字】【或者】段落【进行】进【一步】【的解】释&#xff0c;【所以】常【用来】【解释】含义&#xff0c;【或者】出处&#xff0c;【而其】【解释】【一般】在书【…

mysql服务器程序_MySQL服务器

1、安装通常系统在成功安装之后就已经自带MySQL服务器以及客户端了。查询MySQL及其相关文件是否安装&#xff1a;rpm -qa | grep perlrpm -qa | grep mysql如果没有安装&#xff0c;则可以使用yum进行安装&#xff1a;yum -y install perl-DBIyum -y install perl-DBD-MySQLyum…

Java中List的contains方法,你用对了吗?

Java语言中的List是我们处理集合时经常会用到的。而List定义了一个contains方法&#xff0c;用以判断一个集合中是否包含指定的一个对象。 大家应该有用到过吧&#xff0c;可是你真的会用&#xff0c;用对了吗&#xff1f; 看看下面的代码。 上图代码中&#xff0c;创建了两个…

mysql初体验学习笔记_【MySQL】mycli初体验

早就听说mycli很好用&#xff0c;今天打算在本地测试机上装一下体验一把。安装方法很是简单&#xff1a;一、安装依赖&#xff1a;yum install python-pip python-devel二、安装myclipip install mycli这样就安装完了。三、使用方法[rootlocalhost .pip]# mycli --helpUsage: m…

ArrayList类contains方法实现原理

以ArrayList集合示例 思考&#xff1a;contains方法如何执行&#xff1f; public static void main(String [] args){List<String> listnew ArrayList<String>(); list.add("张三"); System.out.println(list.contains("张三"); }分析contai…

Mybatis源码分析之(一)搭建一个mybatis框架(写一个mybatis的Demo)

数据库工作&#xff1a; 首先准备工作&#xff0c;安装mysql&#xff0c;并且新建一张t_demo表 CREATE TABLE t_demo (name varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,id int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT4 DEFAUL…

后端开发 java_Java后端开发三年,你不得不了解的JVM

JAVA程序员&#xff0c;三年是个坎&#xff0c;如果过了三年你还没有去研究JVM的话&#xff0c;那么你这个程序员只能是板砖的工具了。下面来个JVM的解析可好&#xff1f;JVM是Java Virtual Machine(Java虚拟机)的缩写&#xff0c;也就是指的JVM虚拟机&#xff0c;属于是一种虚…

Mybatis源码分析之(二)根据配置文件创建SqlSessionFactory(Configuration的创建过程)

SqlSessionFactoryBuilder.build创建SqlSessionFactory&#xff08;粗略走一步流程&#xff09; 看完上篇文章后&#xff0c;你对mybatis应该有个大概的了解了&#xff0c;那么我们知道new SqlSessionFactoryBuilder().build是框架的入口&#xff0c;我们到SqlSessionFactoryB…

Mybatis源码分析之(三)mapper接口底层原理(为什么不用写方法体就能访问到数据库)

mybatis是怎么拿sqlSession 在 上一篇的时候&#xff0c;我们的SqlSessionFactoryBuilder已经从xml文件中解析出了Configuration并且返回了sessionFactory。 然后我们要从session;中拿到sqlSession public class DefaultSqlSessionFactory implements SqlSessionFactory {pr…

mysql count distinct case when_统计符合条件的去重过的数量 - - count distinct if case

现有表结构&#xff1a;CREATE TABLE example_dataset (id int(11) unsigned NOT NULL AUTO_INCREMENT,tel bigint(11) DEFAULT NULL,gender varchar(11) DEFAULT NULL,PRIMARY KEY (id)) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4;插入数据INSERT INTO example_da…

Mybatis源码分析之(六)mybatis拦截器(Interceptor)的实现原理

文章目录前言InterceptorChain保存所有的Interceptor创建四大对象都走ConfigurationInterceptorChain增强对象方法Plugin封装动态代理&#xff0c;让你使用Mybatis拦截器更简单Invocation&#xff0c;让我们能在拦截器中使用动态代理类中的invoke方法中的对象调用时序图小结前言…