跨域资源共享CORS
所有文档

          API网关

          跨域资源共享CORS

          1. 跨域资源共享CORS介绍

          1.1 两种验证模式

          跨域资源共享 CORS 的验证机制分两种模式:简单请求和预先请求。

          当请求同时满足下面三个条件时,CORS 验证机制会使用简单模式进行处理。

          1. 请求方法是下列之一:
          • GET
          • HEAD
          • POST
          1. 请求头中的 Content-Type 请求头的值是下列之一:
          • application/x-www-form-urlencoded
          • multipart/form-data
          • text/plain
          1. Fetch规范定义了CORS安全头的集合(跨域请求中自定义的头属于安全头的集合)该集合为:
          • Accept
          • Accept-Language
          • Content-Language
          • Content-Type (需要注意额外的限制)
          • DPR
          • Downlink
          • Save-Data
          • Viewport-Width
          • Width

          否则CORS验证机制会使用预先请求模式进行处理。

          1.2 简单请求模式

          简单请求模式下,浏览器直接发送跨域请求,并在请求头中携带 Origin 的头,表明这是一个跨域的请求。服务器端接到请求后,会根据自己的跨域规则,通过 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 响应头,来返回验证结果。

          简单请求模式

          应答中携带了跨域头 Access-Control-Allow-Origin。使用 Origin 和 Access-Control-Allow-Origin 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://cloud.baidu.com 的访问,该首部字段的内容如下:

          Access-Control-Allow-Origin: http://cloud.baidu.com

          现在,除了 http://cloud.baidu.com,其它外域均不能访问该资源。

          1.3 预先请求模式

          浏览器在发现页面发出的请求非简单请求,并不会立即执行对应的请求代码,而是会触发预先请求模式。预先请求模式会先发送 Preflighted requests(预先验证请求),Preflighted requests 是一个 OPTIONS 请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。在得到服务器的跨域授权后才能发送真正的 HTTP 请求。

          OPTIONS 请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。服务器收到 OPTIONS 请求后,设置 Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers、Access-Control-Max-Age 头部与浏览器沟通来判断是否允许这个请求。如果 Preflighted requests 验证通过,浏览器才会发送真正的跨域请求。

          预先请求模式

          请求中的跨域头 Access-Control-Request-Method 告知服务器,实际请求将使用 GET 方法。请求中的跨域头 Access-Control-Request-Headers 告知服务器,实际请求将携带两个自定义请求首部字段:x-ca-nonce 与 content-type。服务器据此决定该实际请求是否被允许。

          应答中的跨域头 Access-Control-Allow-Methods 表明服务器允许客户端使用 GET 方法发起请求。值为逗号分割的列表。

          应答中的跨域头 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 x-ca-nonce 与 content-type。与 Access-Control-Allow-Methods 一样,Access-Control-Allow-Headers 的值为逗号分割的列表。

          应答中的跨域头 Access-Control-Max-Age 表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。

          2. 在 API 网关中实现跨域资源共享

          2.1 实现简单请求模式

          API 网关默认所有 API 允许跨域访问,因此如果用户的 API 后端服务的应答中不做特殊返回,API 网关会返回允许所有域跨域访问的相关头。

          image.png

          下面是一个示例:

          客户端的 API 请求

          GET /simple HTTP/1.1
          Host: bdcloudapi.com
          orgin: cloud.baidu.com
          content-type: application/x-www-form-urlencoded; charset=utf-8
          accept: application/json; charset=utf-8
          date: Tue, 05 Nov 2019 11:04:10 GMT

          后端服务应答

          HTTP/1.1 200 OK
          Date: Tue, 05 Nov 2019 11:04:10 GMT
          Content-Type: application/json; charset=UTF-8
          Content-Length: 12
          {"200","OK"}

          API网关应答

          HTTP/1.1 200 OK
          Date: Tue, 05 Nov 2019 11:04:10 GMT
          Access-Control-Allow-Origin: *
          Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH
          X-Bce-Request-Id: 63c4a3a9-8636-4510-a54f-595fa74069e4
          Content-Type: application/json; charset=UTF-8
          Content-Length: 12
          {"200","OK"}

          从上面三个报文可以看出,API网关会对用户的后端服务应答做一定修改,增加两个跨域头:

          Access-Control-Allow-Origin: *
          Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS,PATCH

          这个跨域头的意思是,本 API 允许所有域的请求访问,允许跨域的请求方法包括请求头中列出的七种。

          如果用户需要定制针对简单请求的应答的跨域头,只需要在后端服务应答中,增加 Access-Control-Allow-Origin 这个跨域头即可,后端服务应答中的头会默认覆盖掉API网关自己增加的头。下面是一个例子,这个例子中的 API 只允许 cloud.baidu.com 这一个域访问:

          客户端的 API 请求

          GET /simple HTTP/1.1
          Host: bdcloudapi.com
          orgin: cloud.baidu.com
          content-type: application/x-www-form-urlencoded; charset=utf-8
          accept: application/json; charset=utf-8
          date: Tue, 05 Nov 2019 11:04:10 GMT

          后端服务应答

          HTTP/1.1 200 OK
          Access-Control-Allow-Origin: cloud.baidu.com
          Access-Control-Allow-Methods: GET
          Date: Tue, 05 Nov 2019 11:04:10 GMT
          Content-Type: application/json; charset=UTF-8
          Content-Length: 12
          {"200","OK"}

          API网关应答

          HTTP/1.1 200 OK
          Access-Control-Allow-Origin: cloud.baidu.com
          Access-Control-Allow-Methods: GET
          X-Bce-Request-Id: 63c4a3a9-8636-4510-a54f-595fa74069e4
          Date: Tue, 05 Nov 2019 11:04:10 GMT
          Content-Type: application/json; charset=UTF-8
          Content-Length: 12
          {"200","OK"}

          2.2 实现预先请求模式

          浏览器使用 OPTIONS 方法来发送预先请求,以获取服务器对跨域请求的要求信息。

          我们可以在 API 网关中配置一个 API,将该 API 的方法设置为 OPTIONS,并且匹配所有子路径。这样就能让预先请求路由到该 API,返回允许跨域请求的响应。

          API 的创建过程可参考 API 相关文档,其中需要注意的配置要点有以下几方面。

          1. 将安全认证方式设置为“无认证”

          image.png

          1. 将请求路径设置为“/”
          2. 勾选“匹配所有子路径”
          3. 将请求方法设置为“OPTIONS”

          image.png

          上一篇
          Model管理
          下一篇
          后端使用函数计算