案例回顾
当点击页面上的一个按钮触发表达提交的方式有多种
<form action="" method="post" >
<input type="hidden" id="ipt" />
<input type="submit" value="提交" />
</form>
当点击按钮 提交 form 表单,如果网络延迟,
1、此刻我重复刷新页面。会请求多次action地址。
2、此刻如果我点击后退,也会请求多次action
3、此刻如果我重复点击按钮,也会多次 action(废话)
如何 解决 刷新页面,前进后退 的方式 导致重复提交的问题
最简单的方式是:使用ajax 请求。异步处理
当我使用 如下 ajax 异步 方式,无论我刷新,访问历史浏览记录,前进,后退, 都不会造成表单重复提交。
不过仅仅使用ajax 是完全不够的。。
js 端
1、可以 加入 布尔值参数,判断是否多次点击
2、按钮灰度也可以
$.ajax({ type: "post", async: false, url: CONTEXT_PATH + "/svlt03", data: param, dataType: "text", success: function (z) { // window.open(z); $("body").append("<div>" + z + "</div>"); } });
服务器端
使用session 来控制 是否为多次提交
jsp中生成 token存入session
页面中藏起来。。
服务端。读取request带来的session
如果两个token相同表示第一次提交
token不同则表示多次提交。
只要满足第一次提交后就可以清空 session中 token值
如果session 没有过期。
相同浏览器打开新的窗口 共用一个session
如果 更换浏览器 则 是一个新的session
判断是否是一个新的session,获得 sessionId 就可以知道
<%@ page import="self.yzx.services.tokenServices" %><%-- Created by IntelliJ IDEA. User: yzx Date: 2018/3/7 Time: 9:26 To change this template use File | Settings | File Templates. 通过session防止表单重复提交 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String tkSession = new tokenServices().getSessionToken(); session.setAttribute("tks", tkSession); session.setMaxInactiveInterval(10); String context_path = request.getContextPath(); %> <html> <head> <script>var CONTEXT_PATH = '<%=context_path%>'; </script> <script type="text/javascript" src="<%=context_path%>/js/jquery-1.10.2.js"></script> <title>Title</title> </head> <body> <input id="tkSession" type="hidden" value="<%=tkSession%>"/> <input type="checkbox" class="product" value="apple" price="4"/>苹果 <input type="checkbox" class="product" value="banana" price="3"/>香蕉 <input type="checkbox" class="product" value="orange" price="8"/>橘子 <br> <input type="button" id="btn" value="提交" onclick="sbt()"/> <form action="/lt/svlt03" method="post"> <input type="submit" value="提交aa"> </form> </body> </html> <script> function sbt() { var tken = $("#tkSession").val(); var param = new Object(); var choice = ""; $(".product:checked").each(function (index, value, array) { var p = $(this).attr("price"); var n = $(this).val(); choice += "{" + n + ":" + p + "},"; }) param['choice'] = "{" + choice.substr(0, choice.length - 1) + "}"; param['tken'] = tken; $.ajax({ type: "post", async: false, url: CONTEXT_PATH + "/svlt03", data: param, dataType: "text", success: function (z) { // window.open(z); $("body").append("<div>" + z + "</div>"); } }); } </script>
package self.yzx.services; import sun.misc.BASE64Encoder; import java.util.Random; import java.util.UUID; public class tokenServices { public String getSessionToken() { String uuid = UUID.randomUUID().toString(); String nowTime = String.valueOf(System.currentTimeMillis()); String result = uuid + nowTime; BASE64Encoder base64Encoder = new BASE64Encoder(); String encode = base64Encoder.encode(result.getBytes()); return encode; } }
package yzx.sv.lt; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import self.yzx.impl.Svlt02Services; import self.yzx.services.tokenServices; import self.yzx.util.FileUtils; import yzx.sv.lt.BaseServelt.BaseServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.util.List; import java.util.Map; import java.util.Random; public class servletSVLT03 extends BaseServlet { private static final Logger logger = LogManager.getLogger(servletSVLT03.class); protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { excute(request, response); } public void excute(HttpServletRequest request, HttpServletResponse response) throws IOException { String session_tks = String.valueOf(request.getSession().getAttribute("tks")); String id = request.getSession().getId(); String param_tks = request.getParameter("tken"); String choice = request.getParameter("choice"); System.out.println(choice); try { //int time = (int) (Math.random() * 1000 * 5); int time = 5000; System.out.println("休息" + time + "毫秒"); Thread.sleep(time); } catch (Exception e) { } System.out.println(id + ":" + request.getSession().getAttribute("choice")); request.getSession().setAttribute("choice", choice); StringBuffer result = new StringBuffer(); if ("null".equals(session_tks)) { result.append("session 过期"); } else if (param_tks.equals(session_tks)) { result.append("相等"); } else { result.append("不相等"); } result.append(id + ":" + request.getSession().getAttribute("choice")); //request.getSession().invalidate(); FileUtils fileUtils = new FileUtils(); fileUtils.write(result, request, response); } }