不仅是重复提交表单,提交Ajax请求的时候也面临这个问题。比如新增数据的时候,重复刷新表单或者连点两次按钮都有可能重复提交相同的数据。对前端来说,有一种解决方法是点击提交按钮后立即让按钮失效,不能再点击第二次;或者是在前端脚本校验完数据后,提交数据前,让按钮失效。
但是,毕竟前端脚本是运行在不受我们控制的用户设备上;何况让按钮失效的做法也实在是太笨了。所以,我们还是要在自己的服务端里解决。
步骤&原理
首先,服务器要生成一串随机字符串 String,然后把 String 存储在服务器里,同时也发送给用户。
在用户提交数据时,必须将此 String 连同数据一起提交给服务器。
当服务器接收到提交的数据时,首先拿出存储在服务器上的 String 和用户提交的 String 进行对比;并且在对比完成时立即重置服务器端的 String。
若对比一致则通过;不一致则认为重复提交了。
为什么这么判定?假设服务器最开始生成的 String 是1,那么第一次接收到提交的数据时(对比后,且无论对比是否一致)String 就被重置成了 2,。第二次提交数据(即重复提交)时,提交的数据全都没变,String仍然还是之前的 1,但是已经和服务器上的 2 不一致了,所以认定是重复提交。
利用 Session
服务肯定是多用户使用的,如何保证每个用户的 String 都属于各自所有呢?这就依赖于会话了:每个客户端与服务端都是一个独立的可区分的会话,依赖于其可区分的性质,可以为每个会话存储一份属于它自己的 String。
所以就用到了会话控制 Session;在 Session 中存储这个 String。
其实这类问题不可避免的会提到用户输入,实践中在处理用户输入的时候一定要严格检查,不能轻易的信任用户输入,要做好防注入、防XSS等。
安全无小事!!!