在开发项目的时候对于用户信息,验证码之类的信息,我的逻辑是将其保存在session中,当验证码比对或者后面需要用到用户信息的可以直接从session中获取值。今天在登录的时候验证码每次怎么登录怎么不成功,后台能得到前台的传值,但在后台获取session的时候取到的值为null,发现原来每次请求过来产生的session的sessionId都不一样。在以前使用前端代理没有问题,后来使用后台进行
在这里使用的是CORS进行跨域
CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS还是存在一些限制,如下图所示
/**
* 设置跨域响应header
* @param res
*/
public static void setCorsHeader(HttpServletResponse res,String domain){
res.setHeader("Access-Control-Allow-Origin", domain);
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");//允许跨域的请求方式
res.setHeader("Access-Control-Max-Age", "3600");//预检请求的间隔时间
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, Access-Token");//允许跨域请求携带的请求头
res.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true
}
这里的domain是在properties文件定义的
#跨域请求domain,这里设为这个固定的地址不成功
#its.cors.domain=http://127.0.0.1:8084
its.cors.domain=*
从上面的配置Header看出虽然设置了
res.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true
但是每次请求的sessionId都不同,后来发现
Access-Control-Allow-Credentials 是true的时候。 Access-Control-Allow-Origin"的值不能为*。
所以把跨域设置改为
/**
* 设置跨域响应header
* @param res
*/
public static void setCorsHeader(HttpServletResponse res,HttpServletRequest request ){
res.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");//允许跨域的请求方式
res.setHeader("Access-Control-Max-Age", "3600");//预检请求的间隔时间
res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,Access-Control-Allow-Headers");//允许跨域请求携带的请求头
res.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true
}
这样就不用每次不同的地址请求都能够动态的获取,而不用定死一个,同时Access-Control-Allow-Headers设为* 则会报错如下
Failed to load http://192.168.0.222:8084/dm/kanban/carusecount?param=%7B%22areaId%22%3A-1%2C%22startTime%22%3A%222018-08-20+10%3A12%3A00%22%2C%22endTime%22%3A%222018-08-31+11%3A00%3A00%22%2C%22countType%22%3A1%2C%22sum%22%3A0%7D: Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
另外前台的ajax也要做更改
JQuery
$.ajax({
url:url,
//加上这句话
xhrFields: {
withCredentials: true
},
crossDomain: true,
success:function(result){
alert("test");
},
error:function(){
}
});
Fetch
设置 credentials: “include”
getData: function (v, callback, errorCallBack) {
let url = URL + '/list?version='+v;
fetch(url, {
method: 'GET',
credentials: "include"
}).then((response)=>response.json())
.then((responseJsonData)=> {
callback && callback(responseJsonData);
}).catch((error)=> {
});
},
Angular
设置{‘withCredentials’:true}
function get($scope,$http){
$http.post(url,{v1:'name_eu'},{'withCredentials':true}).success(function(data){ $scope.var= data; }); }
至此,问题得到解决