如何防止表单重复提交

问题

在看Java Web 深入分析时, 看到表单重复提交问题一节, 如下描述如何解决问题:

要防止表单重复提交, 就要标识用户的每一次访问请求, 使得每一次访问对服务端来说都是唯一的. 为了标识用户的每次访问请求, 可以在用户请求一个表单域时,增加一个隐藏的表单项, 这个表单项的值每一次都是唯一的token. 如:
<form id = "form" method="post">
<input type=hidden name="crsf_token" value="XXX">
</form>
当客户在请求时生成这个唯一的token时, 同时将这个token保存在用户的Session中, 等用户提交请求时检查这个token和当前的Session中保存的是否一致. 如果一致, 则说明没有重复提交, 否则用户提交上来的token已经不是当前这个请求的合法token.

流程图如下:
请求时生成带有token的表单
但是让我迷惑的是: 访问服务器时获得唯一的token标识, 然后提交时带上这个标志, 服务器检测是否和自己Session中的内容一致. 为什么这样就可以防止重复提交? 我提交的第二次, 第三次还是带有相同的token啊, 服务器检测Session中的内容应该还是一致的. 为什么可以防止重复提交?

解决

然后上网查了下资料, 发现应该是作者少提了一点: 处理前移除Session中指定token.
就是说当服务器第一次收到客户端提交时, Session中是能检测到token的, 然后在准备处理时, 应该先移除Session中的指定token. 这样下一次客户端再次提交, 服务器检测token就会发现Session中没有对应token. 就可以拒绝服务.

remove if exist //如果存在, 那么移除

流程图如下:
提交时验证token

优化

然后又想到了有没有什么优化措施, 可以减缓服务器的压力.

服务端的事情没有办法减少, 那么就从客户端入手, 当客户端重复提交时, 通过JavaScript脚本阻止用户提交. 当客户提交表格时, 可以通过JavaScript脚本里的变量来表示用户是否提交. 当然这种方法不可以绝对相信, 黑客可以伪造数据来通过这个检测. 所以服务器端的检测还是必不可少的, 但是可以大幅度减少用户无意识的多次提交表单, 从而减轻服务器压力.

<script>
var isCommitted=false;
function checkPost()
{
    if(!isCommitted)
    {
        isCommitted=true;
        return true;

    }
    else
    {
        alert("不能重复提交表单");
        return false;
    }
}
</script>
<form method="post" onsubmit="return checkPost()">
......
<input type="submit" value="提交">
</form>
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值