cors 跨域:资源共享 协议 、 域名 、 端口不同 就是跨域 跨源资源共享 (CORS)(或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。

浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP认证 相关数据)。

Access-Control-Allow-Origin: * 表明,该资源可以被 任意 外域访问。

备注: 当响应的是附带身份凭证的请求时,服务端 必须 明确 Access-Control-Allow-Origin 的值,而不能使用通配符“*”。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,

二、 两种请求 简单请求(simple request)和非简单请求

简单请求 满足以下条件的请求即为简单请求:

请求方法:GET、POST、HEAD 除了以下的请求头字段之外,没有自定义的请求头

HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type: application/x-www-form-urlencoded、 multipart/form-data、 text/plain

凡是不同时满足上面两个条件,就属于非简单请求。

简单请求与复杂请求的跨域设置 针对简单请求,在进行CORS设置的时候,我们只需要设置

Access-Control-Allow-Origin:* Access-Control-Allow-Origin: 'http://www.yourwebsite.com'

非简单请求 非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。

非简单请求的CORS请求,会在正式通信之前,自动增加一次HTTP查询请求,称为"预检"请求(preflight)。

预检请求 与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

针对复杂请求, "预检"请求的头信息包括两个特殊字段。

1 Access-Control-Request-Method: POST 该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求

2 Access-Control-Request-Headers: Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

Access-Control-Request-Headers: X-CUSTOMER-HEADER, Content-Type

相应的响应头信息为:

Access-Control-Allow-Origin: http://foo.example Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type // 设置max age,浏览器端会进行缓存。没有过期之前真对同一个请求只会发送一次预检请求 Access-Control-Max-Age: 86400

发送cookie CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。

给xhr 设置了withCredentials为true,从而向服务器发送 Cookies,如果服务端需要想客户端也发送cookie的情况,需要服务器端也返回Access-Control-Allow-Credentials: true响应头信息。⚠️注意:对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin的值为“”。这是因为请求的首部中携带了Cookie信息,如果 Access-Control-Allow-Origin的值为“”,请求将会失败。而将 Access-Control-Allow-Origin的值设置为 http://foo.example(请求源),则请求将成功执行。

上次更新:
贡献者: 郑壮