1.不使用转发,而是使用重定向,重定向发了两次请求,我们再次刷新,刷新的第二个请求,而不是第一个。
2.网速较慢的情况,我们让表单中的提交按钮只能提交一次,然后就不能再次点击了
<form action="FormServlet" method="post">
<input type="text" name="username"/><br/>
<input id="btn" type="submit" value="提交">
</form>
<script type="text/javascript">
window.onload=function(){
//点击完以后让按钮变成一个不可用的状态
//获取按钮对象
var btn=document.getElementById("btn");
//为按钮绑定单击响应函数
btn.onclick=function(){
//通过查看文档可将其设置为不能再次提交
//但是有的浏览器通过这个设置后表单也不能提交了
this.disabled=true;
//我们可以手动的提交表单
this.parentNode.submit();
}
}
</script>
3.(推荐使用)
成功提交请求后,点击回退按钮,但是不刷新页面,再次提交。
产生问题的根本原因
服务器端的Servlet不能区分两次请求是不是重复提交的内容
解决
在Servlet中,我们需要在处理请求之前,先来检查表单是否是重复提交。
流程
1.创建一个令牌,要求唯一,不能重复(UUID),并在服务器中保存token
2.放入到浏览器的表单中
3.浏览器提交表单时,会同时将token一起提交
4.服务器在处理请求之前要检查令牌是否有效
5.销毁token
form.jsp
<%
//1.创建token
String token= UUID.randomUUID().toString();
//放入session域中
session.setAttribute("token",token);
%>
<form action="FormServlet" method="post">
<!--2.放入表单中,不刷新页面的话token是不发生改变的 可以将type属性值改为hidden -->
<input type="text" value="<%= token%>" name="token"/>
<input type="text" name="username"/><br/>
<input id="btn" type="submit" value="提交">
</form>
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session中的token
HttpSession session = request.getSession();
String sessionToken =(String)session.getAttribute("token");
//这步很重要!!!uuid是唯一的不能重复的,我们用完一次要销毁一次!
//这里销毁的是属性!不是值!不影响后面的使用!
session.removeAttribute("token");
//获取表单提交过来的token
String requestToken = request.getParameter("token");
if(!requestToken.equals(sessionToken)){
//token不相等
System.err.println("token不相等,重定向至index.jsp");
response.sendRedirect("/GoodsBills/index.jsp");
return;
}
...省略部分代码块;
}