Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[CORS:跨域资源共享] W3C的CORS Specification

[CORS:跨域资源共享] W3C的CORS Specification

作者头像
蒋金楠
发布于 2018-01-15 11:29:00
发布于 2018-01-15 11:29:00
1.4K00
代码可运行
举报
文章被收录于专栏:大内老A大内老A
运行总次数:0
代码可运行

随着Web开放的程度越来越高,通过浏览器跨域获取资源的需求已经变得非常普遍。在我看来,如果Web API不能针对浏览器提供跨域资源共享的能力,它甚至就不应该被称为Web API。从另一方面来看,浏览器作为进入Internet最大的入口,是各大IT公司的必争之地,所以浏览器市场出现了种类繁多、鱼龙混杂的局面。针对这两点,我们迫切需要一种能够被各个浏览器厂商共同遵循的标准来对跨域资源共享作出规范,这就是由W3C指定2的CORS(Cross-Origin Resource Sharing)规范。

目录 CORS是如何工作的? 对响应报头的授权 预检机制 是否支持用户凭证

一、CORS是如何工作的?

基于Web的资源共享涉及到两个基本的角色,即资源的提供者和消费者。针对我们前面演示的应用场景,即显示在浏览器中的某个Web页面通过调用Web API的方式来获取它所需的资源,资源提供者为Web API本身,通过发送Ajax请求来调用Web API的JavaScript程序为资源的消费者。

CORS旨在定义一种规范让浏览器在接收到从提供者获取的资源时能够正决定是否应该将此资源分发给消费者作进一步处理。CROS利用资源提供者的显式授权来决定目标资源是否应该与消费者共享。换句话说,浏览器需要得到提供者的授权之后才会将其提供的资源分发给消费者。那么,资源的提供者如何进行资源的授权,并将授权的结果告诉浏览器呢?

具体的实现其实很简单。如果浏览器 自身提供对CROS的支持,由它发送的请求会携带一个名为“Origin”的报头表明请求页面所在的站点。对于前面我们演示实例中调用Web API获取联系人列表的请求来说,它就具有如下一个“Origin”报头。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   1: Origin: http://localhost:9527

资源获取请求被提供者接收之后,它可以根据该报头确定提供的资源需要共享给谁。资源提供者的授权通过一个名为“Access-Control-Allow-Origin”的响应报头来承载,其报头值表示得到授权的站点。一般来说,如果资源的提供者认可了当前请求的“Origin”报头携带的站点,那么它会将该站点作为“Access-Control-Allow-Origin”响应报头的值。

除了指定具体的源并对其作针对性授权之外,资源提供者还可以将“Access-Control-Allow-Origin”报头值设置为“*”对所有消费者授权。换言之,如果作了这样的设置,意味着由其提供的是一种公共资源,所以在做此设置之前需要慎重。如果针对请求着的授权不被允许,资源提供者可以将此响应报头值设置为“null”,或者让响应不具有此报头。

当浏览器接收到包含资源的响应之后,会提取此“Access-Control-Allow-Origin”响应报头的值。如果此值为“*”或者包含的源列表包含此前请求的源(即请求的“Origin”报头值),意味着资源的消费者获取了提供者获取和操作资源的权限,所以浏览器会允许JavaScript程序操作获取的资源。如果此响应报头不存在或者其值为“null”,客户端JavaScript程序针对资源的操作会被拒绝。

二、对响应报头的授权

资源提供者除了通过设置“Access-Control-Allow-Origin”报头对提供的主体资源进行授权之外,还可以通过设置另一个名为“Access-Control-Expose-Headers”的报头对响应报头进行授权。具体来说,此“Access-Control-Expose-Headers”的报头用于设置一组直接暴露给客户端JavaScript程序的响应报头,没有在此列表的响应报头 对于客户端JavaScript程序是不可见的。

但是由此实现的针对响应报头的授权针对简单响应报头是无效的,客户端JavaScript程序总是具有获取它们的权限。对于CORS规范来说,这里所谓的“简单响应报头(Simple Response Header)”包含如下6种。

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

我们知道用于实现Ajax请求的XMLHttpRequest具有一个getResponseHeader方法,调用它会返回一组响应报头的列表。按照这里介绍的针对响应报头的授权原则,只有在“Access-Control-Expose-Headers”报头中指定的报头和简单响应报头才会包含在该方法返回的列表中

三、预检机制

W3C的CORS规范将跨域资源请求划分为两种类型,一种被称为“简单请求(Simple Request)”。要弄清楚CORS规范将那些类型的跨域资源请求划分为简单请求的范畴,需要额外了解几个名称的含义,其中包括“简单(HTTP)方法(Simple Method)”、“简单(请求)报头(Simple Header)”和“自定义请求报头(Author Request Header/Custom Request Header)”。

CORS规范将GET、HEAD和POST这三个HTTP方法视为“简单HTTP方法”,而将请求报头Accept, Accept-Language, Content-Language以及采用如下三种媒体类型的报头Content-Type称为“简单请求报头”

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

请求的报头包含两种类型,一类是通过浏览器自动生成的报头,另一种则是由JavaScript程序自行添加的报头(比如调用XMLHttpRequest的setRequestHeader方法可以为生成的Ajax请求添加任意报头),后者被称为“自定义报头”。

CORS规范将服务如下条件的跨域资源请求划分为简单请求:请求采用简单HTTP方法,并且其自定义请求报头空或者所有自定义请求报头均为简单请求报头。之所以作如此划分是因为具有这些特性的请求不是以更新(添加、修改和删除)资源为目的,服务端对请求的处理不会导致自身维护资源的改变。

对于简单跨域资源请求来说,浏览器将两个步骤(取得授权和获取资源)合二为一,由于不涉及到资源的改变,所以不会带来任何副作用(Side Effect)。如果针对请求的处理过程会涉及到对资源的改变,这样做就会有问题了。按照CORS规范的规定,浏览器应该采用一种被称为“预检(Preflight)”的机制来完成非简单跨域资源请求。

所谓预检机制就是说浏览器在发送真正的跨域资源请求前,先发送一个预检请求(Preflight Request)。预检请求为一个采用HTTP-OPTIONS方法的请求,这是一个不包含主体的请求,同时用户凭证相关的报头也会被剔除。基于真正资源请求的一些辅助授权的信息会包含在此预检请求的相应报头中。除了代表请求页面所在站点的“Origin”报头之外,如下所示的是两个典型的请求报头。

  • Access-Control-Request-Method:真正跨域资源请求采用的HTTP方法。
  • Access-Control-Request-Headers:真正跨域资源请求携带的自定义报头列表。

资源的提供者在接收到预检请求之后,根据其提供的相关报头进行授权检验,具体的检验逻辑即包括确定请求站点是否值得信任,以及请求采用HTTP方法和自定义报头是否被允许。如果预检请求没有通过授权检验,资源提供者一般会返回一个状态为“400, Bad Reuqest”的响应。反之则会返回一个状态为“200, OK”的响应,授权相关信息会包含在响应报头中。除了上面介绍的“Access-Control-Allow-Origin”和“Access-Control-Expose-Headers”报头之外,预检请求的响应还具有如下3个典型的报头。

  • Access-Control-Allow-Methods:跨域资源请求允许采用的HTTP方法列表。
  • Access-Control-Allow-Headers:跨域资源请求允许携带的自定义报头列表。
  • Access-Control-Max-Age:浏览器可以将响应结果进行缓存的时间(单位为秒),这样可以让浏览器避免频繁地发送预检请求。

浏览器在接收到预检响应之后,会根据响应报头确定后续发送的真正跨域资源请求是否会被接受,相关的检验包括针对服务端允许站点以及HTTP方法和自定义请求报头(利用响应报头“Access-Control-Allow-Methods”和“Access-Control-Allow-Headers”)的检验。具体的检验逻辑如下

  • 通过请求的“Origin”报头表示的源站点必须存在于“Access-Control-Allow-Origin”响应报头标识的站点列表中。
  • 响应报头“Access-Control-Allow-Methods”不存在,或者预检请求的“Access-Control-Request-Method”报头表示的请求方法在其列表之内。
  • 预检请求的“Access-Control-Request-Headers”报头存储的报头名称均在响应报头“Access-Control-Allow-Headers”表示的报头列表之内。

只有在确定服务端一定会接受的情况下,浏览器才会发送真正跨域资源请求。预检响应结果会被浏览器缓存,在“Access-Control-Max-Age”报头设定的时间内,缓存的结果将被浏览器用户进行授权检验,所以在此期间不会再有预检请求发送。

四、是否支持用户凭证

在默认情况下,利用XMLHttpReuqest发送的Ajax请求不会携带用户凭证相关的敏感信息,这里的用户凭证类型包括Cookie、HTTP-Authentication报头以及客户端X.509证书(采用支持客户端证书的TLS/SSL)等。如果需要用户凭证附加到Ajax请求上,需要将XMLHttpReuqest的withCredentials 属性设置为True。

对于CORS来说,是否支持用户凭证也是授权检验的一个环节。换句话说,只有在服务端显式支持用户凭证的情况下,携带了用户凭证的请求才会被认为是有效的。在W3C的CORS规范来说,服务端利用响应报头“Access-Control-Allow-Credentials”来表明自身是否支持用户凭证。

也就是说,如果客户客户端JavaScript程序利用一个withCredentials属性为true的XMLHttpReuqest发送了一个跨域资源请求,但是浏览器得到的响应中不具有一个值为“true”的响应报头“Access-Control-Allow-Credentials”,它对获取资源的操作将会浏览器拒绝。

上面我们对W3C的CORS规范作了概括性的介绍,由于篇幅所限,很多的细节并没有涉及。如果读者朋友们对此有兴趣,我个人强烈推荐直接阅读W3C的官方文档。由于官方文档的文字描述较为“生硬”,可能需要多读几遍才能将资源提供者和浏览器如何处理资源授权流程搞清楚。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-12-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
通过扩展让ASP.NET Web API支持W3C的CORS规范
让ASP.NET Web API支持JSONP和W3C的CORS规范是解决“跨域资源共享”的两种途径,在《通过扩展让ASP.NET Web API支持JSONP》中我们实现了前者,并且在《W3C的CORS Specification》一文中我们对W3C的CORS规范进行了详细介绍,现在我们通过一个具体的实例来演示如何利用ASP.NET Web API具有的扩展点来实现针对CORS的支持。 目录 一、ActionFilter OR HttpMessageHandler 二、用于定义
蒋金楠
2018/01/15
2.7K0
通过扩展让ASP.NET Web API支持W3C的CORS规范
跨域资源共享(CORS)
简单先了解一下CORS,方便我们后续去挖一些CORS的漏洞,最近CORS也是比较火的!
黑伞安全
2019/10/16
4.3K0
跟我一起探索 HTTP-跨源资源共享(CORS)
跨源资源共享CORS,是一种基于HTTP头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。
用户1418987
2023/10/16
9990
跟我一起探索 HTTP-跨源资源共享(CORS)
【网络知识补习】❄️| 由浅入深了解HTTP(五)跨源资源共享(CORS)
跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。
呆呆敲代码的小Y
2021/08/20
1.6K0
【网络知识补习】❄️| 由浅入深了解HTTP(五)跨源资源共享(CORS)
跨域资源共享(CORS)是什么?
出于安全原因,浏览器会限制脚本发起的跨域 HTTP 请求,除非服务器同意访问。譬如服务器对预检请求的响应 Header 中有 Access-Control-Allow-Origin: *,那么跨域请求即可正确访问。
Learn-anything.cn
2021/11/24
1.3K0
Web漏洞 | CORS跨域资源共享漏洞
有关于浏览器的同源策略和如何跨域获取资源,传送门 -->浏览器同源策略和跨域的实现方法
Gcow安全团队
2020/03/19
9.4K0
Web漏洞 | CORS跨域资源共享漏洞
你不知道的CORS跨域资源共享
了解下同源策略 源(origin)*:就是协议、域名和端口号; 同源: 就是源相同,即协议、域名和端口完全相同; 同源策略:同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源; 同源策略的分类: DOM 同源策略:即针对于DOM,禁止对不同源页面的DOM进行操作;如不同域名的 iframe 是限制互相访问。 XMLHttpRequest 同源策略:禁止使用 XHR 对象向不同源的服务器地址发起 HTTP 请求。 不受同源策略限制: 页面中的链接,
keyWords
2019/03/20
1.1K0
你不知道的CORS跨域资源共享
ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事
从编程的角度来讲,ASP.NET Web API针对CORS的实现仅仅涉及到HttpConfiguration的扩展方法EnableCors和EnableCorsAttribute特性。但是整个CORS体系不限于此,在它们背后隐藏着一系列的类型,我们将会利用本章余下的内容对此作全面讲述,今天我们就来讨论一下用于定义CORS授权策略的EnableCorsAttribute特性背后的故事。 目录 一、CorsPolicy 二、CorsPolicyProvider 三、CorsPoli
蒋金楠
2018/01/15
1.6K0
ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事
Cors跨域(一):深入理解跨域请求概念及其根因
做Web开发的小伙伴对“跨域”定并不陌生,像狗皮膏药一样粘着几乎每位同学,对它可谓既爱又恨。跨域请求之于创业、小型公司来讲是个头疼的问题,因为这类企业还未沉淀出一套行之有效的、统一的解决方案。
YourBatman
2021/06/24
2.9K1
HTTP的同源策略与跨域资源共享(CORS)机制
准确的说,同源策略是指,浏览器内部在发起如下请求时,该来源必须是当前同源的HTTP资源:
用户7657330
2020/08/14
1.6K0
HTTP的同源策略与跨域资源共享(CORS)机制
跨域资源共享 CORS 详解
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能
ruanyf
2018/04/12
1.2K0
跨域资源共享 CORS 详解
CORS解决跨域问题
浏览器中,网站A的网络请求访问网站A的资源(图片,HTTP请求)是很顺畅的,而想访问网站B的资源,就要面对跨域资源访问的问题了。面对跨域问题,有很多的解决方案,本文讨论使用 CORS 来解决的方案。
张云飞Vir
2020/03/27
2.2K0
Flask配置Cors跨域
跨域是指:浏览器A从服务器B获取的静态资源,包括Html、Css、Js,然后在Js中通过Ajax访问C服务器的静态资源或请求。即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源。
用户1558882
2019/03/04
4K0
Flask配置Cors跨域
跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
在《通过扩展让ASP.NET Web API支持W3C的CORS规范》中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持,实际上ASP.NET Web API自身也是这么做的,该自定义HttpMessageHandler就是System.Web.Http.Cors.CorsMessageHandler。 1: public class CorsMessageHandler : DelegatingHandler 2: {
蒋金楠
2018/01/15
3K0
跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
什么是 CORS(跨源资源共享)?
现代网页比以往任何时候都使用更多的外部脚本和资产。默认情况下,JavaScript 遵循同源策略,只能调用与运行脚本在同一域中的 URL。那么,我们怎样才能让我们的 JavaScript 支持的页面使用外部脚本呢?
用户4235284
2023/10/14
1.1K0
什么是 CORS(跨源资源共享)?
掌握并理解 CORS (跨域资源共享)
咱们从一个例子开始,假设咱们有一个网站,网址为 http://good.com:8000/public:
前端小智@大迁世界
2022/06/15
2.6K0
掌握并理解 CORS (跨域资源共享)
CORS
CORS(https://links.jianshu.com/go?to=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh- CN%2Fdocs%2FGlossary%
ruochen
2021/12/04
3.4K0
跨域资源共享的使用
本文主要介绍了跨域资源共享(CORS)的相关知识,包括CORS的工作原理、服务器端如何配置支持CORS、如何发起跨域请求以及如何处理响应等。此外,还提供了关于浏览器对CORS请求的处理流程和可能遇到的错误情况的说明。
IMWeb前端团队
2017/12/29
1.7K0
跨域资源共享的使用
CORS跨域
当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
张炳
2019/08/02
2.3K0
CORS跨域
实战 解决CORS error(跨域资源共享错误)
我通过自建cos源cos.xpblog.cn,托管本博客(www.xpblog.cn)的静态文件,引用ttf文件时,出现了CORSerror(跨域资源共享错误)
小屁的博客
2022/05/13
50.4K2
实战 解决CORS error(跨域资源共享错误)
相关推荐
通过扩展让ASP.NET Web API支持W3C的CORS规范
更多 >
交个朋友
加入腾讯云技术交流站
前端技术前沿探索 云开发实战案例分享
加入前端工作实战群
前端工程化实践 组件库开发经验分享
加入前端趋势交流群
追踪前端新趋势 交流学习心得
换一批
领券
一站式MCP教程库,解锁AI应用新玩法
涵盖代码开发、场景应用、自动测试全流程,助你从零构建专属AI助手
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档