继昨天的跨域【跨域问题】jsonp赋值失败,今天又出现了一个新的问题,就是用Ajax跨域请求之后被踢退登录了,因为昨天用的是伪代码说明的,所有在A、B项目之间没有登录动作,不存在踢退问题,然而今天上线之后这个问题就出现了。
原因说明:
因为在默认情况下,跨源请求是不会提供凭证的(cookie、HTTP认证及客户端SSL证明等),所以这次的Ajax请求会被服务器认为是一次新的请求,并不携带任何凭证,被踢退登录也是正常的。
解决方案:
设置XMLHttpRequest 的 withCredentials 属性
- 默认值为false。在获取同域资源时设置 withCredentials 没有影响。
- true:在跨域请求时,会携带用户凭证。
- false:在跨域请求时,不会携带用户凭证;返回的 response 里也会忽略 cookie。
所以要在Ajax中添加设置:xhrFields: {withCredentials: true}:
$.ajax({
type: "post",
async: false,
url: "...",
dataType: "json",
//添加此项设置
xhrFields: {
withCredentials: true
},
success: function (data) {
}
});
服务端也要进行相应设置:
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
我们在客户端设置了withCredentials=true参数,那服务器端也要通过在响应Header中设置Access-Control-Allow-Credentials = true来运行客户端携带凭证的访问。通过对Credentials参数的设置,就可以保持跨域Ajax时传递的Cookie。
这里需要注意的是,Access-Control-Allow-Origin 不能用 * 通配符,因为当服务器端 Access-Control-Allow-Credentials = true时,参数Access-Control-Allow-Origin 的值不能为 '*' 。
我们需要重新设置Access-Control-Allow-Origin的值,当服务器端接收到请求后,在返回响应时,把请求的域Origin填写到响应的Header信息里,即谁访问我,我就允许谁。