对CORS OPTIONS预检请求的一些思考

前后端分离模大势所趋,跨域问题更是老生常谈。

《程序员应对浏览器同源策略的姿势》一文提到三种跨域请求方案,重点讲述了w3c和浏览器厂商推出的CORS规范。

同源策略  所谓同源是指域名、协议、端口相同。不同源的浏览器脚本(javascript、ActionScript、canvas)在没有明确授权的情况下,不能读写对方的资源, 这是浏览器最基本的安全规范。

CORS是w3c和浏览器厂商为解决跨域资源共享问题而推出的标准方案:

浏览机器一旦发现跨域请求,就会自动添加一些附加的头信息,有时还会多出一次附加的请求(浏览器自动完成,用户不会察觉),服务器响应特定标头Access-Control-,体现对跨源访问的授权态度。


今天我主要想要聊一聊CORS中的预检请求

当前端使用脚本请求一个跨域资源时,如果是非简单请求(下文会解释),浏览器会自动帮你先发出一个OPTIONS查询请求,称为预检(cors-preflight-request),作用是询问服务器当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段;只有得到肯定答复,浏览器才会发出正式的跨域请求。

"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

该请求header中会包含以下两个字段:

  • Access-Control-Request-Method: 该字段的值对应当前请求类型,例如 GET、POST、PUT等等。浏览器会自动处理。

  • Access-Control-Request-Headers: 该字段的值对应当前请求可能会携带的额外的自定义header字段名,多个字段用逗号分割。浏览器会自动处理,将请求中非简单的header字段全部列出来,例如标识请求流水的x-request-id,用于Auth鉴权的Authorization 字段。

对于OPTIONS请求,按照规范实现的服务端会响应一组HTTP header,但不会返回任何实体内容。如果服务端支持该跨域请求,建议返回204状态码(返回200也可以);如果不支持,建议返回403状态码(返回404或其他错误状态码也可以)。

响应的header可以包含以下字段:

  • Access-Control-Allow-Origin: 允许哪些域被允许跨域,例如 http://qq.com 或 https://qq.com,或者设置为* ,即允许所有域访问

  • Access-Control-Allow-Credentials: 是否携带票据访问(对应fetch方法中credentials),当该值为true时,Access-Control-Allow-Origin 不允许设置为*

  • Access-Control-Allow-Methods: 标识该资源支持哪些方法,例如:POST, GET, PUT, DELETE

  • Access-Control-Allow-Headers: 标识允许哪些额外的自定义 header 字段和非简单值的字段

  • Access-Control-Max-Age: 表示可以缓存Access-Control-Allow-Methods和Access-Control-Allow-Headers提供的信息多长时间,单位秒,由服务端和浏览器默认值共同决定。

  • Access-Control-Expose-Headers: 通过该字段指出哪些额外的 header 可以被支持。

由此可见,当触发预检时,一次AJAX请求会消耗掉两个TTL,严重影响性能。

那么如何节省掉OPTIONS请求来提升性能呢?从上文可以看出,有两个方案:

  1. 发出简单请求

只要同时满足以下两个条件,就属于简单请求
(1)使用下列方法之一:

  • head

  • get

  • post

(2)请求的Heder是

  • Accept

  • Accept-Language

  • Content-Language

  • Content-Type: 只限于三个值:application/x-www-form-urlencoded、multipart/form-data、text/plain

不同时满足上面的两个条件,就属于非简单请求。很明显,我们常见的Post请求且Content-Type=application/json也属于非简单请求,也会触发预检请求。

>   如果不方便改造为简单请求,只有使用方案2了。

  1. 服务器端设置Access-Control-Max-Age字段

当第一次请求该URL时会发出OPTIONS请求,浏览器会根据返回的Access-Control-Max-Age字段缓存该OPTIONS预检请求的响应结果。在缓存有效期内,该资源的请求(URL和header字段都相同的情况下)不会再触发预检。(chrome 打开控制台可以看到,当服务器响应Access-Control-Max-Age时只有第一次请求会有预检,后面不会了。注意要开启缓存,去掉disable cache勾选)

但是要注意的是,该缓存只针对这一个请求 URL 和相同的 header,无法针对整个域或者模糊匹配 URL 做缓存(当然也可以考虑封装一下,固定一个接口地址,传不同的body内容)。

以上便是对CORS OPTIONS预检请求的一些思考,希望对同学们有所帮助!

最后是Abp vNtext配置CORS的示例:

private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
{context.Services.AddCors(options =>{// 无阻塞跨域options.AddPolicy(DefaultCorsPolicyName, builder =>{builder.SetIsOriginAllowed(_ => true).AllowCredentials().AllowAnyHeader().WithMethods(HttpMethods.Get, HttpMethods.Post, HttpMethods.Put, HttpMethods.Delete).SetPreflightMaxAge(TimeSpan.FromHours(24));});});
}

- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age

-  程序员应对浏览器同源策略的姿势

关注并星标我们
更多干货及最佳实践分享

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

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

相关文章

2020计算机单招的大专,2020专科和单招的区别

单招即单招招生是国家授权高职院校独立组织考试录取的一种方式,必须于高考前完成录取。众所周知,单招学校大部分是专科学校,那么,单招和专科有什么区别呢?下面是小编为大家收集的关于2020专科和单招的区别_选择单招有什么好处。希…

前端跨域请求get_前端实现跨域访问

1.ajax方式跨域直接使用jsonp即可dataType : "jsonp",2.使用getJson跨域获取数据$.getJSON("http://api.taobao.com/apitools/ajax_props.do&jsoncallback?",function (data) {alert(data);});执行原理:发送请求时需要传一个callback的回调…

如何在 ASP.NET Core 中使用 NLog 的高级特性

NLog 是一个开源的轻量级日志框架,提供了丰富的日志路由和管理功能,同时 NLog 也是非常容易的去配置和扩展,其实在之前的文章中我已经讨论过了 Nlog,在这篇我准备继续和大家讨论一下 NLog 的更多高级功能。接下来看看如何通过 .co…

计算机模拟分子设计,计算机模拟分子材料.pdf

计算机模拟分子材料.pdf计算机模拟与材料分子设计计算机模拟与材料分子设计CCCCompuomputttterer SiSiSiSimumullllaatititition anon andddd MMMMoollllecuecullllarar DDDDesesiiiigngnDalian Universityof Technology Graduate Course, Lecture 5 2010 AutumnLectureLecture…

python是用来初始化_python的初始化运行了哪些?

下面的3个print一个是在模块下面,一个是函数里面,一个是类名下面(不在方法里面)1、 运行这段代码可以发现第3行和11行可以打印出来。第7行没有打印出来。所以可以放心,函数或者方法里面就算有错误,不调用它是不可能报错的&#xf…

强烈推荐:SiteServer CMS开源免费的企业级CMS系统!

说到CMS,大家都知道织梦、帝国CMS、HPCMS、动易等知名老牌的!这些东西也可以拿来就用,上次看到一个个人开源的cms:MCMS。基于SpringBoot 2架构,前端基于vue、element ui。每月28定期更新版本,为开发者提供…

计算机函数公式中怎么合并合并,Excel用函数和公式瞬间实现把表格全部合并到一个表中去...

将多张工作表汇总到一张工作表,这是什么意思呢?可以理解为把表格全部合并到一个表中去,之前使用VBA代码实现,本文将教会大家一种快速的方法,用函数和公式瞬间实现多表合并。例如:有N多个以月份命名的excel工…

permutations python_为什么Python的itertools.permutations包含重复项? (当原始列表重复时)...

为什么Python的itertools.permutations包含重复项? (当原始列表重复时)普遍认为,n个不同符号的列表有n! 排列。 但是,当符号不明确时,在math和其他地方最常见的惯例似乎是只计算不同的排列。 因此,列表[1, …

. NET5一出,. NET岗面试普遍喊难,真相是…

.NET高级开发/架构师笔试题TOP101、如何设计一个高并发系统?2、如何实现一个.Net5 IOC框架?3、100W并发4G数据,10W并发400G数据,如何设计Redis存储方式?4、如何实现负载均衡Hash一致性算法?5、DotNetty能够…

计算机所有数据的表示方式都是用,计算机数据表示

1、进制1.1 进制的由来进制:是一种进位的方式。x进制,表示逢x进1。计算机的电子原件的状态:开,关。那么,我们表达数据的时候,也是按照开,关的状态来表示的。如果我们表达数据仅仅使用这两种昨天…

数据库年月日时分秒_数据库基本使用系列(二)

书接上回,上回说到数据库的发展历史,存储引擎以及在库层面的一些操作,这次来讲一下数据库中的一些基本的一些数据格式以及对表的一些操作。数据类型数据库提供的数据类型,包括整数类型、浮点数类型、定点数类型、位类型、日期和时…

C# 9 新特性 —— 增强的模式匹配

C# 9 新特性 —— 增强的模式匹配IntroC# 9 中进一步增强了模式匹配的用法,使得模式匹配更为强大,我们一起来了解一下吧SampleC# 9 中增强了模式匹配的用法,增加了 and/or/not 操作符,而且可以直接判断属性,来看一下下…

arma3自定义服务器,Arma3 生存服架设教程,武装突袭3游戏服务器架设

Arma3 生存服架设教程,武装突袭3游戏服务器架设此教程仅适用于Windows系统,独立服务器或者家用电脑都可以用本教程简单搭设Exile Mod。开服其实很简单, 只要你有足够的耐心!1.首先 在你的服务器上打开steam下载ArmA 3 Server (SteamCMD 则使用…

netcore读取json文件_【NET Core】.NET Core中读取json配置文件

在.NET Framework框架下应用配置内容一般都是写在Web.config或者App.config文件中,读取这两个配置文件只需要引用System.Configuration程序集,分别用System.Configuration.ConfigurationManager.AppSettings["SystemName"];//读取appSettings配…

前端数据层落地实践

源宝导读:天际移动平台经过重构改版,近期正式发布了1.0版本,我们在低代码开发方面做了进一步增强。本文主要围绕前端Model、前端业务逻辑(领域模型)、数据层与视图层解耦(包装器模式)3个方面,给大家分享一下统一数据层方案的设计思…

计算机内存条只认了一个,怎么解决Win10插入2个4G内存条却只显示4G?

为了提高 Win10系统 的运行速度,有用户在自己的电脑中,插入了2根4G内存,可是发现电脑只能显示4G而不是8G,奇怪的是使用卤蛋师却可以检测到8G内存,这是怎么回事呢?我们该如何解决呢?下面&#xf…

scanf 返回值_scanf函数

一、函数scanf()是C语言中的一个输入函数。与printf函数一样&#xff0c;都被声明在头文件stdio.h里&#xff0c;因此在使用scanf函数时要加上#include <stdio.h>。它是格式输入函数&#xff0c;即按用户指定的格式从键盘上把数据输入到指定的变量之中。函数的原型为&…

【Git】Git-常用命令备忘录(三)

git作为一个vcs&#xff08;version control system&#xff09;&#xff0c;是越用越香&#xff0c;那么还有哪些比较香的地方呢&#xff01;&#xff1f;1.远程仓库中拉取指定分支一定遇到这种情况&#xff0c;github看到一个心仪的开源仓库&#xff0c;但是分支太多&#xf…

jenkins换服务器找不到包,服务器重启后Jenkins项目部分丢失问题解决方法

UVALive 4670 Dominating Patterns --AC自动机第一题题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多. 解法:AC自动机入门模板题. 代码: #include #include phpMyAdmin - 错误 您应升级到 MySQL 5&period;5&period;0 或更高版本&comma;解决办法。…

mysql表类型_MySQL表类型的选择

P131)创建表时的默认引擎是InnoDB&#xff0c;如果要修改默认的存储引擎&#xff0c;可以在参数文件中设置default-table-type。查看当前的默认存储引擎&#xff0c;可以使用一下命令&#xff1a;创建新表的时候可以通过增加ENGINE关键字设置新建表的存储引擎。也可以通过ALTER…