KM盒子APP制作软件

IntraWeb处理后退和Session与Cookie教程

时间:2018-11-22 13:06 点击:

问题场景:

页面login.html 登陆后跳转页面admin.html

这时禁止浏览器或者手机返回按键退回页面login.html

但其他页面支持前进、后退

操作方法可能有多种,例如可能设置个全局变量bClick := true ;然后在OnBackButton事件触发时判断TIWResyncInfo.FormName页面是否允许后退。

TIWResyncInfo = record
    CurrentTrackId: Cardinal;
    SubmittedTrackId: Cardinal;
    FormName: string;
    FormClassName: string;
    ExecuteForm: Boolean;
    SetActiveForm: Boolean;
    RecreateActiveForm: Boolean;
    Handled: Boolean;
  end;

或者可以在OnRewriteURL中判断ARewriteURL包含页面名称和参数。

在这里举一种最简单的方法,操作步骤:

1、设置BackButtonOptions-Mode属性bmEnable,即默认不自动添加任何防止后退的代码。

Mode有四个选项:(bmInterceptGlobal, bmInterceptForm, bmEnable, bmDisableCompat)

默认选项bmDisableCompat 使用兼容旧版的处理方法防止后退。

选择bmInterceptGlobal时IntraWeb将生成JavaScript代码来防止后退按钮的使用。

选择bmInterceptForm时IntraWeb将检查IWForm.PreventBackButton产生的后退记录防止退出应用窗体。

选择bmEnable时IntraWeb将不添加何任防止后退的代码。

2、admin.html页面中添加自定义的js禁止后退代码:

procedure TIndexForm.IWAppFormCreate(Sender: TObject);
begin
//禁止后退
AddToInitProc('history.pushState(null, null, document.URL);'+
        'window.addEventListener("popstate", function () {'+
            'history.pushState(null, null, document.URL);'+
        '});');
end;

3、其他相关js代码

// 浏览器回退禁止
function noBack () {
// 历史记录栈中记录页数
var numberOfEntries = window.history.length;
if (window.history && window.history.pushState) {
window.addEventListener('popstate', function() {
// 当点击浏览器的 后退和前进按钮 时才会被触发,
window.history.pushState('forward', null, '');
window.history.forward(1);
});
}
// 新弹出页对应
if (numberOfEntries != 1) {
// 页面间跳转用
window.history.pushState('forward', null, '');
window.history.forward(1);
}
};
//从缓存中获取上一个页面的url,并跳转 window.location.replace(document.referrer);
使用replace() 方法不会在 History 对象中生成一个新的记录。

再讲下页面的登陆和登出

1、登陆时

UserSession.UserID := DMDataMain.FDQuery1['name']; //绑定用户name

UserSession.Time:= IntToStr(DateTimeToUnix(now) - 8 * 60 * 60); //记录时间戳

WebApplication.Response.Cookies.AddCookie('uid', userid, '', Now+1); //写Cookie

2、登出

WebApplication.Response.Cookies.RemoveCookie('uid',''); //删除Cookie

WebApplication.GoToURL('login.html'); //转跳登陆面面

WebApplication.CallBackResponse.AddJavaScriptToExecuteAsCDATA(js);

3、关于session和cookie

session是服务器端的机制,cookie是浏览器端的机制。

Session是把用户的数据写到服务端独占的session中。Cookie是把用户的数据写到用户的当前浏览器中。

通过session可以管理/跟踪会话,可以在用户登录的时候,把用户的登陆信息放进session里面,并在一些内部页面校验是否是当前的session ,以确保当前用户不是游客,并且拥有更多的权限。

例如:添加到购物车,支付购买等。并且通常情况下我们只设置一个session

所以,用户登录时可以把用户信息保存到session域里面。

当你浏览商品,点击购买会提示你还没有登陆,直到登陆后,你的session才开始跟踪你的浏览记录,你才拥有购买的权限。session是保存在服务器的所以相对比较安全。

由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。

intraweb有自己的全局对象GSessions,使用它的属性GSessions.GetCount,就可以获得session总数。用这个属性可以完成统计访问用户总数,控制用户数量,可以为每个session编序号等功能。

cookie的内容主要包括:名字,值,过期时间,路径和域。若不设置过期时间,则表示这个

cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。

在 IW.HTTP.Cookie 单元提供有两个相关类: THTTPCookie、TCookieList; 另外 IWServerController 还有一个 CookieOptions 选项。

读取 Cookie 通常需要Timer定时触发,例如:

procedure TIndexForm.IWTimer1AsyncTimer(Sender: TObject;
  EventParams: TStringList);
var
userid:string;
begin
IWTimer1.Enabled := False;
  userid := WebApplication.Request.CookieFields.Values['uid'];
  if userid = '' then  WebApplication.GoToURL('login.html')
  else
  WebApplication.ShowMessage('用户已登陆,无需要重复登陆!');
end;
{遍历 Cookie}
procedure TIWForm1.IWButton1Click(Sender: TObject);
var
  str: string;
begin
  for str in WebApplication.Request.CookieFields do IWMemo1.Lines.Add(str);
end;



上面介绍了session与cookie两者之间的关系,简单来说:Session放在服务器端。当浏览器关闭就会清空。

Session时间不宜设置过长,否则大量占用服务器内存。Cookie适合长时间保存,在登出时被清除。

验证用户是否登录的逻辑:

1)用户密码登录时,在后台的记住Session

2)如果用户保存登录密码,则记住Cookie,否则把当前用户的Cookie设置为空;

3)每次用户需要向后台进行请求时,进行状态检验:

Session是否存在?若存在,则继续进行请求操作,并将Session的有效时间重新设置一次;

若不存在,则判断cookie是否存在?若存在,使用该cookie完成自动登录,即完成了一次1);

若不存在,则页面重定向到登录页面。

IntraWeb实现方案:

1)、首先在UserSession单元添加一个变量UserID用来标记登陆状态,然后在首页判断UserID是否为空,为空时跳转登陆界面。大于空时用UserID查询数据库取回用户名,用户名=Cookie保存的用户名时进行自动登陆。

if WebApplication.Request.CookieFields.Values['UserID'] = '' then

UserName := WebApplication.Request.CookieFields.Values['UNmae'];

2)、用户登陆成功后向UserID写入标识

UserID := '101';

WebApplication.Response.Cookies.AddCookie('UserID', '101', '', -1);

WebApplication.Response.Cookies.AddCookie('UNmae', 'mingyi', '', -1);

3)、用户选择记住密码时,将密码使用AES加密并保存到Cookie

加密建议使用CnAES单元跨平台通用性好

str := AESEncryptEcbStrToHex(pw,key); //加密

pw := AESDecryptEcbStrFromHex(str,key) //解密

WebApplication.Response.Cookies.AddCookie('PassWord', pw, '', -1)

4)、读取IW_AppName Session,通过用户操作记录判断延长Session过期时间

WebApplication.Request.CookieFields.Values['IW_AppName']);

5)、用户注销登陆时将Session UserID设为空,并删除Cookie记录

UserID := '';

WebApplication.Response.Cookies.RemoveCookie('UserID', '');