把这两天研究的东西记一下,虽然最后验证不可行,毕竟辛苦了两天。
众所周知,keycloak提供的Login页面的登录是直接Form提交的,用户名密码验证失败,返回前台,页面刷新,keycloak自带的messagePerField.existsError('username','password')判断,err信息显示出来。
因为这次要更换Login页面,用keycloak,以前的登录页面是ajax提交,登录失败不会刷新页面,直接弹错误信息。所以希望keycloak也可以用ajax提交。
开始验证,keycloak虽然是ftl的页面,但是不影响用js,先导入jquery包包,然后是熟悉的ajax如下
$.ajax({
url:"${url.loginAction}", // keycloak固定
type:"POST",
data:{略},
success:function(data){
alert("success");
},
error:function(e){
alert("error");
}
});
跑一下试试看,然鹅,常见的400错误,传参不对。就这个几个参数哪儿能出错啊,data各种改,dataType也改来改去,后来才知道dataType是返回值的type,原谅我这个小白。
改来改去还是不行,注意到了url,一开始没怀疑过这货,因为跟form提交用的是同样的url,是没问题的。没办法了,换回form提交,把url打出来看看,还真是这货。form提交的URL里是&,ajax提交的URL里是&
查了下下面几个js的编码方法,都不好使。
escape()、encodeURI()、encodeURIComponent()
还是粗暴一些,直接替换吧,一共有五个常用的,直接换掉,懒得自己写(其实是我的正则表达式不熟),直接百度拿来。
function escape2Html(str) {
var arrEntities={'lt':'<','gt':'>','nbsp':' ','amp':'&','quot':'"'};
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig,function(all,t){return arrEntities[t];});
}
完美换掉,终于OK,接下来要处理一下返回值,看看返回的data里是啥,我去直接把整个html返回来了,keycloak自带的messagePerField.existsError('username','password')放到JS里直接报错,果然人家ftl的东西不能随便用。
还是粗暴一些直接扔页面里,定义个隐藏项目放下。ftl的<#if>插在哪里都可以。
<input type="hidden" id="result" <#if messagePerField.existsError('username','password')>value="NG"</#if>>
然后遍历html,$.each不好用,直接报错,这货只能遍历项目,最开始的html标签就不行了。
查了查,用div挺好使的,如下
var result = $("#result", data).html();
<div id = "result"><#if messagePerField.existsError('username','password')>NG</#if></div>
成功取到NG字符串,判断NG,弹出错误信息。
if ("NG" == result) {
var msg = "项目机密,中略,就是做一个覆盖层,然后popup的样式,其实就是一个div"
$("#msg").html(msg);
}
完美运行,正常弹出错误信息,可以拿着成果去报告可行了,然鹅,又点了一次登录,没反应了。。。。。Debug一下,第二次没进后台。
上网查查呗,还真有,说是URL相同会被浏览器缓存辨别,在URL后面加个new Date,再跑一下,依然如此。打出来看看URL,有了Date确实不一样了,为啥呢。
思来想去,对比了两次发送的请求,除了Date其他完全一样。突然想起来这是keycloak,sessionCode都一样,怎么可能让你二次提交。必须要刷新页面更新sessionCode才可以的吧。
好了到此为止,依然是要刷新页面的吧?
因为我是keycloak小白,所以打了问号,有没有大佬告诉我keycloak里面有没有这个设置,可以不刷新页面也能多次提交的。