网站导航:首页-网络知识-如何通过CORS解决跨域问题

如何通过CORS解决跨域问题

最近更新:2020-06-17

跨域资源共享(Cross-Origin Resource Sharing, CORS)可以解决浏览器向非同源服务器发送ajax请求的问题。CORS的实现已经由浏览器自行完成了,我们要做的只是在HTTP HEADER中添加一些字段即可。跨域请求分为简单请求非简单请求两种,同时满足以下条件的就属于简单请求,其他情况属于非简单请求。

除了上面的三条规则外,还有其他需要同时满足的规则,但由于它们较为复杂,而且通常都是满足的,所以这里就不提了。

在个别浏览器中会有比更加严格的要求,但这些更加严格限制只在个别的几个浏览器中有效。

简单请求

在发送简单请求时,会正常携带请求的信息,只是在请求的HTTP HEADER中添加一个Origin字段,值为当前页面的源(协议、域名、端口)信息。

服务器端可以根据请求的HTTP HEADER中的Origin字段的内容决定是否同意这次跨域请求,如果同意本次跨域请求需要根据具体情况在正常响应内容的同时,在响应的HTTP HEADER中添加如下字段中的一个或多个,如果不同意本次跨域请求则不添加如下HTTP HEADER即可。

字段 是否必选 描述
Access-Control-Allow-Origin 允许跨域访问的源,可以填写与请求的HTTP HEADER中的Origin字段相同,表示允许对应的源进行跨域访问,也可以填写*表示允许任何源跨域访问。
Access-Control-Allow-Credentials 否,但当请求HTTP HEADER中携带Cookie信息时必选 允许响应中携带Cookie时,此值为true,否则应省略此字段。当请求HTTP HEADER中携带Cookie信息时,此值必须为true
Access-Control-Expose-Headers 响应的HTTP HEADER中除了Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma之外允许携带的字段。如果这里没有设置对应的值,则客户端无法拿到对应的字段。

通常客户端在发送ajax请求时也会有一个withCredentials属性,其值为true时表示发送请求时允许携带Cookie,否则表示不允许携带Cookie。当请求地址为同源时,无论此值设置为什么,均允许携带Cookie。

非简单请求

如果要发送的跨域请求不满足简单请求的条件,则会发起非简单请求。对于非简单请求浏览器会首先发起**预检请求**来判断服务器是否允许跨域通信。预检请求使用的请求方法为OPTIONS,其中并不包含请求信息,只是在预检请求的HTTP HEADER中含有如下字段,这些信息是浏览器根据正式发起跨域请求时的参数自动添加的,不需要开发者手动设置。

字段 描述
Origin 发起请求的源(协议、域名、端口)信息。
Access-Control-Request-Method 正式发起跨域请求使用的请求方法。
Access-Control-Request-Headers 正式发起跨域请求时需要携带的HTTP HEADER字段,有多个HEADER时用英文逗号分隔。

服务器端收到预检请求后会根据请求中以上HTTP HEADER的内容决定是否同意这次跨域请求,如果同意本次跨域请求需要根据具体情况在预检请求的响应的HTTP HEADER中添加如下字段中的多个,如果不同意本次跨域请求则不添加如下HTTP HEADER即可。

字段 是否必选 描述
Access-Control-Allow-Origin 允许跨域访问的源,可以填写与请求的HTTP HEADER中的Origin字段相同,表示允许对应的源进行跨域访问,也可以填写*表示允许任何源跨域访问。
Access-Control-Allow-Methods 服务器在正式响应跨域请求时支持的方法,如果允许多种方法可用英文逗号分隔。此值中必须包含但不限于预检请求中Access-Control-Request-Method的值。
Access-Control-Allow-Headers 否,但当遇预检请求的HTTP HEADER中包含Access-Control-Request-Headers字段时必选 服务器在响应跨域请求时支持传递的HTTP HEADER,如果允许在请求中传递多个HTTP HEADER可用英文逗号分隔。此值中必须包含但不限于预检请求中Access-Control-Request-Headers的值。
Access-Control-Allow-Credentials 否,但当请求HTTP HEADER中携带Cookie信息时必选 允许正式响应中携带Cookie时,此值为true,否则应省略此值。当请求HTTP HEADER中携带Cookie信息时,此值必须为true
Access-Control-Max-Age 本次预检请求的有效期,单位为秒。在此时间内的跨域请求直接按照简单请求来处理,不需要发出另一条预检请求。

当浏览器发送了预检请求并收到同意跨域的响应后,会再次按照简单请求的方式发送跨域请求,请求与响应的规则与简单请求相同。

提醒

对于简单请求,只是在请求和响应的HTTP HEADER中新增一个或几个字段,其他信息还是正常传递的。对于预检请求,在请求与响应中只有与CORS相关的字段,并不包含其他信息。

(正文完)

如果您认为本文中存在问题或有任何不足之处,欢迎您在Github:Rivalsa/comment中提交issue

到底线啦,请:返回目录页|返回首页