站请求怎么成功
跨站请求需要服务端同意,在指定请求响应头中设置Access-Control-Allow-Origin
指定该响应允许被哪些域共享。
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: <origin>
将Access-Control-Allow-Origin
设置为我们的域名之后即可成功访问。
如何携带凭据
通过Access-Control-Allow-Origin
可以成功跨站访问,但是我们通过debug
会发现,请求没有携带cookie
,这是因为我们没有在请求中指示是否要使用cookie、authorization、headers
或者TLS
客户端证书等凭据来创建跨站点访问。可以通过请求的withCredentials
属性来开启它。
const xhr = new XMLHtppRequest()
xhr.withCredentials = true
xhr.open('GET', 'http://example.com', true)
xhr.send(null)
我们再刷新请求会发现请求直接报错了,这是因为我们请求指示要求服务器允许使用凭据,但是服务器响应并没有指示允许。这时候还要在响应头中设置Access-Control-Allow-Credentials
为true
来明确允许。除此之外Access-Control-Allow-Origin
不能是通配符比如*
,而是必须是明确的值,就是必须明确允许请求的域
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: <origin>
在旧版的浏览器中,基于上方的配置就能成功在请求中携带cookie
了。
新版本,安全性升级
我们基于上访配置在chrome51
之后的浏览器访问会发现依旧没有携带上cookie
访问,这是因为在chrome51
之后浏览器对cookie
新增了一个会影响跨站携带凭证的属性 SameSite,下面是这个属性的值:
Strict
,严格的,完全禁止第三方cookie
,只有当前网页URL与请求目标一致才会携带。可能造成不好的用户体验,比如从一个github
连接点击进去不会携带cookie
会被判断为未登录Lax
,稍微宽松,大多数不允许第三方cookie
,从导航到目标地址的Get
(链接,预加载请求,GET表单) 除外。None
允许第三方跨站访问携带cookie
,该属性有一个要求,必须同时为cookie
设置Secure
(该值指明cookie只能在https请求中被携带),第三方必须是https
协议的源。
所以除了对新版本中响应的cookie
设置为SameSite=None; Secure
外,请求放必须是https
站点。
Set-Cookie: xxx; SameSite=None; Secure