Cross-Origin Resource Sharing

Cross-Origin Resource Sharing

Who should read this article?

Everyone, really.

More specifically, this article is for web administrators, server developers and front-end developers. Modern browsers handle the client side of cross-origin sharing, including headers and policy enforcement. But the CORS standard means servers have to handle new request and response headers.

What requests use CORS?

不是所有http请求,都会验证CORS的。普通的cdn加载js或者css文件,是不会触发CORS检查的。

This cross-origin sharing standard can enable cross-site HTTP requests for:

This is a general article about Cross-Origin Resource Sharing and includes a discussion of the necessary HTTP headers.

 

Cross-Origin Resource Sharing协议介绍

COR的实现标准就是CORS协议。

对于浏览器来说,COR请求都是Javascript发起的,COR请求有两种:

1、简单的COR请求,它可以直接向外域资源发起请求。它必须仅仅包含简单的方法和头,具体定义看[2] 6.1。

2、如果COR包含复杂的方法和头,它需要发出预检验(Preflight)请求,它先向资源服务器发出一个OPTIONS方法、包含“Origin”头的请求。该回复可以控制COR请求的方法,HTTP头以及验证等信息。只有该请求获得允许以后,才会发起真实的外域请求。

下面是一个简单的COR请求:

<script language="Javascript" type="text/javascript">

var client = new XMLHttpRequest();

client.open("GET", "http://bar.org/b")

client.onreadystatechange = function() { /* do something */ }

client.send()

</script>

假设这个请求所在页面的域是“http://foo.org”。 如果来自“http://bar.org/b”的回复包含这样的头:

Access-Control-Allow-Origin: http://foo.org

则表明,它允许来自“http://foo.org”的跨域请求。

下面的Javascript会发出预检验请求和真实请求:

<script language="Javascript" type="text/javascript">

var client = new XMLHttpRequest();

client.open("GET", "http://bar.org/b")

client.setRequestHeader('Content-Type','text/html')

client.onreadystatechange = function() { /* do something */ }

client.send()

</script>

由于“Content-type: text/html”不是一个简单的头,它会先向"http://bar.org/b"发出一个OPTIONS的HTTP请求。 回复可能包含这样的头:

Access-Control-Allow-Origin: http://foo.org

Access-Control-Max-Age: 3628800

Access-Control-Allow-Methods: GET,PUT, DELETE

Access-Control-Allow-Headers: content-type

"Access-Control-Allow-Origin"表明它允许"http://foo.org"发起跨域请求

"Access-Control-Max-Age"表明在3628800秒内,不需要再发送预检验请求,可以缓存该结果

"Access-Control-Allow-Methods"表明它允许GET、PUT、DELETE的外域请求

"Access-Control-Allow-Headers"表明它允许跨域请求包含content-type头

如果预检验请求获得通过,接下来Javascript就会发起真实的COR请求,过程跟简单的COR请求类似。

CORS协议的实现

现在HTML5的标准如火如荼的在制定和发展中,CORS作为HTML5的一部分,在大部分现代浏览器中有所支持,支持(部分支持)CORS协议的浏览器有IE8+, Firefox5+, Chrome12+, Safari4+

 

WEB跨域资源共享:Cross-origin Resource Sharing(CORS)

跨域资源共享(CORS)请求:通常CORS请求可分为两类,一类是简单请求,另一类则是预检请求。无论何种请求类型,只要服务端响应中未包含正确的首部如Access-Control-Allow-Origin: http://foo.example等,浏览器将报告错误。

简单请求简单请求与普通请求相比,多了请求首部字段Origin,形如Origin: http://foo.example,服务端响应时则多了响应首部字段Access-Control-Allow-Origin,形如Access-Control-Allow-Origin: http://foo.example 或者 *。简单请求须满足所有下述条件:

  • 使用下列方法之一:
    • GET
    • HEAD
    • POST
      • Content-Type :仅POST方法的Content-Type值等于下列之一才算作简单请求:
        • text/plain
        • multipart/form-data
        • application/x-www-form-urlencoded
  • Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width


预检请求:需预检的请求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求,如果服务端同意,再发送实际请求,这样可以避免跨域请求对服务器的用户数据产生未预期的影响。预检请求须满足所有下述条件:

  • 使用了下面任一 HTTP 方法:
    • PUT
    • DELETE
    • CONNECT
    • OPTIONS
    • TRACE
    • PATCH
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (but note the additional requirements below)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  •  Content-Type 的值不属于下列之一:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

 

posted @ 2021-10-20 16:05  ChuckLu  阅读(38)  评论(0编辑  收藏  举报