1. API网关实现跨域资源共享(CORS)
1.1. 跨域带来的安全问题及浏览器的限制访问
当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。比如,站点 http://www.aliyun.com 的某 HTML 页面通过img的src请求 http://www.alibaba.com/image.jpg 。 网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。
出于安全原因,浏览器限制从页面脚本内发起的跨域请求,有些浏览器不会限制跨域请求的发起,但是会将结果拦截了。 这意味着使用这些API的Web应用程序只能加载同一个域下的资源,除非使用CORS机制(Cross-Origin Resource Sharing 跨源资源共享)获取目标服务器的授权来解决这个问题。

上图画的是典型的跨域场景,目前主流浏览器为了用户的安全,都会默认禁止跨域访问,但是主流浏览器都支持W3C推荐了一种跨域资源共享机制(CORS)。服务器端配合浏览器实现CORS机制,可以突破浏览器对跨域资源访问的限制,实现跨域资源请求。

1.2. 跨域资源共享CORS介绍
1.2.1. 两种验证模式
跨域资源共享CORS的验证机制分两种模式:简单请求和预先请求。
当请求同时满足下面三个条件时,CORS验证机制会使用简单模式进行处理。
1.请求方法是下列之一:
GET HEAD POST 2.请求头中的Content-Type请求头的值是下列之一:
application/x-www-form-urlencoded multipart/form-data text/plain 3.Fetch规范定义了CORS安全头的集合(跨域请求中自定义的头属于安全头的集合)该集合为:
Accept Accept-Language Content-Language Content-Type (需要注意额外的限制) DPR Downlink Save-Data Viewport-Width Width 否则CORS验证机制会使用预先请求模式进行处理。
2.简单请求模式:
简单请求模式,浏览器直接发送跨域请求,并在请求头中携带Origin的头,表明这是一个跨域的请求。服务器端接到请求后,会根据自己的跨域规则,通过Access-Control-Allow-Origin和Access-Control-Allow-Methods响应头,来返回验证结果。

应答中携带了跨域头 Access-Control-Allow-Origin。使用 Origin 和 Access-Control-Allow-Origin 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://www.aliyun.com 的访问,该首部字段的内容如下:
Access-Control-Allow-Origin: http://www.aliyun.com
现在,除了 http://www.aliyun.com ,其它外域均不能访问该资源。
2.3 预先请求模式
浏览器在发现页面发出的请求非简单请求,并不会立即执行对应的请求代码,而是会触发预先请求模式。预先请求模式会先发送Preflighted requests(预先验证请求),Preflighted requests是一个OPTION请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。在得到服务器的跨域授权后才能发送真正的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 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。