此应用程序的许多用途将需要> 15分钟才能完成,因此用户将经常提交表单,以便发现他们的会话状态消失,并且他们需要重新登录.
如果发生这种情况,我想保留原始表单提交,如果他们成功登录,继续并执行表单提交,就像会话未过期一样.
我已经通过控制器中的auto()方法处理了身份验证内容 – 如果您请求需要身份验证的操作并且您当前未登录,则会重定向到login()方法,该方法会显示登录表单,然后在提交后处理它.似乎应该可以在auto方法重定向到login()时存储请求和任何表单参数,然后在login()成功时将它们拉回来 – 但我不完全确定最好的以通用/标准/可重用方式获取或存储此信息的方法. (我正在考虑将它存储在会话中,然后在它被撤回后将其删除;如果这看起来是个坏主意,那还有其他问题需要解决.)
是否有标准的“最佳实践”或烹饪方法来做到这一点?
(一个皱纹:这些表格是通过POST提交的.)
解决方法
尽管如此,我会考虑覆盖Catalyst :: Plugin :: Session-> delete_session方法,以便$c-> request-> body_parameters的任何内容被序列化并保存(可能是数据库) )以便以后恢复.您可能希望对POST参数进行一些初步检查,以确保它们符合您的期望.
同样,create_session需要负责将这些数据从数据库中拉回来并使其可用于原始表单操作.
这似乎是一个混乱的情况,我倾向于重复我的第一句……
更新:
无论您使用delete_session还是auto,反常的问题仍然存在:您无法在会话中存储此信息,因为超时事件会破坏会话.你必须将它存储在更永久的地方,以便它能够在会话重新初始化时幸存下来. Catalyst :: Plugin :: Session本身正在使用Storable,你应该可以使用以下内容:
use Storable; ... sub auto { ... unless (...) { #ie don't do this if processing the login action my $formitems = freeze $c->request->body_parameters; my $freezer = $rs->update_or_create( {user => $c->user,formitems => $formitems} ); # Don't quote me on the exact Syntax,I don't use DBIx::Class } ... my $formitems = $c->request->body_parameters || thaw $rs->find({$user => $c->user})->formitems || {} ; # use formitems instead of $c->request->body_parameters from here on in
基础表可能有(用户CHAR(x),formitems TEXT)或类似的.也许是一个时间戳,以便没有任何太陈旧的东西得到恢复.您可能还想存储正在处理的操作,以确保检索到的表单项属于正确的表单.你知道你的应用程序的问题比我更好.