为什么会有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", ...
随机推荐
- Github开源项目(企业信息化基础平台)
JEEPlatform 一款企业信息化开发基础平台,可以用于快速构建企业后台管理系统,集成了OA(办公自动化).SCM(供应链系统).ERP(企业资源管理系统).CMS(内容管理系统).CRM(客户关 ...
- redis设置开机启动
方式一 1.设置redis.conf中daemonize为yes,确保守护进程开启,也就是在后台可以运行.(设置为yes后,启动时好像没有redis的启动界面,不知道为什么) #vi编辑redis安装 ...
- 使用Mybatis进行多表联查操作
(1)增加一个测试数据库shop_order,sql语句如下: CREATE DATABASE `shop_order`; USE `shop_order`; CREATE TABLE `t_user ...
- 【java设计模式】【结构模式Structural Pattern】合成模式Composite Pattern
package com.tn.pattern; import java.util.Vector; public class Client { public static void main(Strin ...
- PL/SQL Developer使用技巧(部分)
PL/SQL Developer使用技巧(部分) 关键字自动大写 在sql命令窗口中输入SQL语句时,想要关键字自动大写,引人注目该怎么办呢? 一步设置就可以达成了.点击Tools->Prefe ...
- ASP.NET Core使用SkiaSharp实现验证码
前言 本文并没有实现一个完成的验证码样例,只是提供了在当前.NET Core 2.0下使用Drawing API的另一种思路,并以简单Demo的形式展示出来. Skia Skia是一个开源的二维图形库 ...
- (转)iOS-Runtime知识点整理
runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...
- VS2012 未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService
最近新换了系统还真是问题多多呀!! 系统更新补丁后打开 VS2012 ,新建C#项目的时候出现这个问题 VS2012 未找到与约束ContractName Microsoft.VisualStudio ...
- jsDOM编程-拖拽层
页面样式代码: <!doctype html><html><head><meta http-equiv="content-type" co ...
- C# 给枚举类型增加一个描述特性
前言 相信很多人对枚举并不陌生,枚举可以很方便和直观的管理一组特定值.如果我们在页面上直接输出我们希望匹配的汉语意思或则其他满足我们需求的语句就更好了,当然,通常小伙伴们都会再页面上if(enum== ...