ajax跨域请求时未携带cookies
背景:
需求开发过程中,在m.qwe.com
域名的页面下请求 dev.qwe.com
的异步接口需要将m.qwe.com
下的cookie携带过去,cookie示例如下
Name: userId
Value: GYGBEDGJGBHBWDOI=
Domain:.qwe.com
Path: /
Expires/Max-Age: 2052-11-30T12:01:40.000Z
看了一下domain是.qwe.com
,那么当ajax
请求 dev.qwe.com
接口的时候应该默认把cookies带过去才对,但是为啥看Request headers
的时候并没有cookie呢?询问了下rd是不是服务器没有进行相关配置,得到的回复是不需要特殊配置,之前也是在m.qwe.com
域名的页面下请求 dev.qwe.com
的接口都是带着cookie的
过程:
感觉事情没有这么简单,首先翻了下线上,发现确实在m.qwe.com
域名的页面下请求过 dev.qwe.com
,并且有cookie传递,但是使用的是jsonp
的方式,该方式会默认将cookie携带过去。于是使用本地的node服务模拟了下跨域请求的情况。 将dev.qwe.com
、m.qwe.com
都代理到本地node服务上,和rd返回同样的access-control-allow-origin: *
,启动服务后发现跨域请求可以正常返回,但确实没有携带cookie。
于是在node服务里配置
app.use( ( request , response , next ) => {
response.header( 'Access-Control-Allow-Origin' , 'http://m.qwe.com')
response.header( 'Access-Control-Allow-Credentials' , true)
next();
})
在前端配置携带验证信息
$.ajax({
url: `http://dev.qwe.com/brocker/list`,
xhrFields: { withCredentials: true }, // 重点
success(res){
// success cb
}
})
在此请求后就可以在Request headers
里看到cookie啦。
结论:
前面说的看了一下domain是.qwe.com,那么当ajax请求dev.qwe.com接口的时候应该默认把cookies带过去才对
这句话大错特错!!!虽然.qwe.com
看着像是所有*.qwe.com
的域名都会携带cookie,但是其实是说在没有其他配置的情况下,所有符合*.qwe.com
的域名下的js都可以获取这些cookie。
在CORS标准中做了规定,默认情况下,浏览器在发送跨域请求时,不能发送任何认证信息(credentials
), 如cookies
和HTTP authentication schemes
。除非xhr
的withCredentials
属性设置为true
。
所以由于cookies
也是一种认证信息,在跨域请求中,客户端必须手动设置xhr
的withCredentials
属性为true
,且服务端也必须允许request能携带认证信息(即response header
中包含Access-Control-Allow-Credentials:true
),这样浏览器才会自动将cookie加在request header中。
另外,要特别注意一点,一旦跨域request能够携带认证信息,server端一定不能将Access-Control-Allow-Origin
设置为*,而 必须设置为请求页面的域名。