• 主页
  • vue前后端分离使用fetch 跨域请求时 session失效问题解决

vue前后端分离使用fetch 跨域请求时 session失效问题解决

前台是vue使用fetch请求后台的登录方法,但是前台浏览器的控制台中的sessionid没有,要么就是跟后台的sessionid不一致,导致后台取验证码的时候是null,因为验证码是后台存在session中

在用fetch进行网络请求的时候,发现每次请求到服务端的时候,他的sessionId都是不一样的,后面排查原来是在请求的时候fetch默认是不会带上本地jsessionId,以至于服务端无法接收到,所以会重新创建一个新的session。

针对这个问题,完整写法是:主要是credentials:'include'是解决跨域session丢失的问题,加上这一行以后,前端浏览器中的sessionid和后台列印的sessionid是一致的,但是参数传不过来,最后加了一个method:'post',就可以了

letfd=newFormData();

fd.append('username',this.userName);

fd.append('password',this.userPwd);

fd.append('checkCode',this.code);

fetch(`${apiUrl}/login`,{

method:'post',

body:fd,

credentials:'include'

}).then((res)=>res.json()).

then((res)=>{

console.log(res);

}).catch((res)=>console.log(res));

后台代码

(註:

response.setHeader("Access-Control-Allow-Origin",":8080";);

response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE");

response.setHeader("Access-Control-Max-Age","3600");

response.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");

response.setHeader("Access-Control-Allow-Credentials","true");//是否支持cookie跨域

后台什么都不需要加,根本不需要加跨域这些东西)。

javascript使用fetch进行跨域请求时默认是不带cookie的,所以会造成session失效。

fetch(url,{

method:'POST',

credentials:'include',

headers:{'Content-Type':'application/x-www-form-urlencoded',

},

body:JSON.stringify({

data:options.data

})

})credentials:'include'可以是fetch带上cookie。但是问题了来。

原来在伺服器端设置header(php伺服器)

header("Access-Control-Allow-Origin:*");

会报错:

Awildcard'*'cannotbeusedinthe'Access-Control-Allow-Origin'headerwhenthecredentialsflagistrue.Origin':8000'isthereforenotallowedaccess.

可以看到不允许使用『*』号了,那么就改成访问域名(这里是本地调用所以是:8000)

header("Access-Control-Allow-Origin::8000");

改完后再次发送请求,还是报错

Credentialsflagis'true',butthe'Access-Control-Allow-Credentials'headeris''.Itmustbe'true'toallowcredentials.Origin':8000'isthereforenotallowedaccess.

说'Access-Control-Allow-Credentials头必须是true,那么继续增加

header("Access-Control-Allow-Credentials:true");

增加完后可以正常访问了,而且session也有了。

ps:fetch有个mode是no-cors,发现设置后返回的status是0,查资料后

no-corsmodeisonlytoCDNcontent,suchasscripts,CSSandimage,youcannotbeusedforgettingdata,response.status=0isrightbehavior

no-cors模式只能用来获取CDN内容,比如脚本,css文件和图片,如果用来获取数据比如json格式就会返回status=0

针对于解决前后台sessionid一致问题以后又遇到参数传递不到后台,最后这样解决:

终极方案(推荐使用):

既然fetch不会自动转FormData,那我们自己new一个FormData,直接传给body。

在FormData中也可以传递字节流实现上传图片的功能。参考:

[javascript]viewplaincopy

letformData=newFormData();

formData.append("name","admin");

formData.append("password","admin123");

etch(url,{

method:'POST',

headers:{},

body:formData,

).then((response)=>{

if(response.ok){

returnresponse.json();

}

).then((json)=>{

alert(JSON.stringify(json));

).catch((error)=>{

console.error(error);

);

这样我们就可以在Server端获取到name和password的值了。