This is the 10th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
1. Why are forms submitted repeatedly?
- In the case of network delay, users click the Submit button for several times, resulting in repeated form submission
- After the user submits the form, clicking the “refresh” button causes the form to be submitted repeatedly. (Clicking the browser’s refresh button means that the browser does the same thing again as it did last time, because this also causes the form to be submitted repeatedly.)
- After the user submits the form, click the “Back” button of the browser to return to the form page and submit it again
2. Solutions
2.1 Front-end Solutions (Treating symptoms rather than the root cause)
2.1.1 Use JavaScript to control Form submission only once
Main code:
<form action="${pageContext.request.contextPath}/servlet/DoFormServlet"&western nsubmit ="return dosubmit()" method="post"> User name: <input type="text" name="username">
<input type="submit" value="Submit" id="submit">
</form>
<head>
<title>Form Form</title>
<script type="text/javascript">
var isCommitted = false;// Whether the form has submitted the identity. Default is false
function dosubmit(){
if(isCommitted==false){
isCommitted = true;// After submitting the form, set the form submitted flag to true
return true;// Return true for the form to submit normally
} else {
return false;// Return false and the form will not be submitted}}</script>
</head>
Copy the code
2.1.2 Set the submit button as unavailable after submission (experience may not be good)
Main code:
function dosubmit(){
// Get the form submission button
var btnSubmit = document.getElementById("submit");
// Make the form submit button unavailable to prevent the user from clicking the submit button again
btnSubmit.disabled= "disabled";
// Return true to allow the form to be submitted normally
return true;
}
Copy the code
2.1.3 Close the page after submission (user experience may be poor)
2.1.4 Refresh page data after submission At this time, get the primary key ID of this record, and check whether the primary key ID exists at the back end to insert or modify it
2.2 Back-end Solutions
2.2.1 Use Session to prevent forms from being submitted repeatedly
Main steps:
- Generate a unique random identifier, technically known as a Token, on the server side and store this Token in the current user’s Session domain
Token generated class
public class TokenProccessor {
/* * Singleton design pattern (ensure that the class object is only one in memory) *1, private class constructor *2, create a class object *3, provide a public method, return the class object */
private TokenProccessor(a){}private static final TokenProccessor instance = new TokenProccessor();
/** * returns the object of class *@return* /
public static TokenProccessor getInstance(a){
return instance;
}
/** * Generate Token * Token: Nv6RRuGEVvmGjB+jimI/gw== *@return* /
public String makeToken(a){
String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
// Data fingerprint 128 bits long 16 bytes MD5
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(token.getBytes());
// Base64 encoding -- Any binary encoding plaintext character adfsdfsdfsf
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
throw newRuntimeException(e); }}}Copy the code
String token = TokenProccessor.getInstance().makeToken();// Create a token
System.out.println("Token generated in FormServlet:"+token);
request.getSession().setAttribute("token", token); // Use session to store tokens on the server
request.getRequestDispatcher("/form.jsp").forward(request, response);// Jump to the form.jsp page
Copy the code
- Send the Token to the client in the Form Form, use a hidden field in the Form Form to store the Token, and submit the Form with the Token to the server
<form action="${pageContext.request.contextPath}/servlet/DoFormServlet" method="post"> <%-- Token generated using hidden domain storage --%> <%-- <input type="hidden" name="token" value="<%=session.getAttribute("token") % >"> --%> <%-- Fetch tokens stored in session using an EL expression --%> <input type="hidden" name="token" value="${token}"/> User name: <input type="text" name="username">
<input type="submit" value="Submit">
</form>
Copy the code
- On the server side, check whether the Token submitted by the client is consistent with the Token generated by the server side. If the Token is inconsistent, it is repeatedly submitted. In this case, the server side can not process the repeatedly submitted form. If they are the same, the form submission is processed and the id stored in the current user’s Session field is cleared after processing.
/** * Check whether the token submitted by the client is the same as the token generated by the server *@param request
* @return* True the user resubmitted the form * false the user did not resubmit the form */
private boolean isRepeatSubmit(HttpServletRequest request) {
String client_token = request.getParameter("token");
//1. If there is no token in the form data submitted by the user, the user submitted the form repeatedly
if(client_token==null) {return true;
}
// Retrieve tokens stored in Session
String server_token = (String) request.getSession().getAttribute("token");
//2. If the current user's Session does not have a Token, the user submitted the form repeatedly
if(server_token==null) {return true;
}
//3. The tokens stored in the Session are different from the tokens submitted to the form. The user submitted the form repeatedly
if(! client_token.equals(server_token)){return true;
}
return false;
}
Copy the code
In doGet method:
boolean b = isRepeatSubmit(request);// Check whether the user is submitting again
if(b==true){
System.out.println("Please do not re-submit.");
return;
}
request.getSession().removeAttribute("token");// Remove tokens from session
System.out.println("Handle user submission requests!!");
Copy the code
For the problem of [Scenario 2] and [Scenario 3] causing the form to be submitted repeatedly, since it cannot be solved on the client side, it should be solved on the server side, and session is needed to solve it on the server side. The token method can solve scenario 2 and scenario 3.
2.3 Front-end plus back-end solution
After the front-end submission, the page will get a loading animation. After the back-end processing is completed, the primary key ID of this data will be returned to the front-end. When the front-end second request, the primary key ID can be attached to the value.
Conclusion:
There are four common methods:
- Method 1: Disable the “Submit (register)” button. When the user clicks the submit registration button for the first time, the transaction has already been submitted, but the network is unstable and may not respond in time. In this case, the user may think that the submit button has not been clicked and click the submit button again.
This is not consistent with our business logic, so we can make the submit button unavailable immediately after the user clicks the submit button for the first time (e.g., go gray) and the user will not submit again.
-
Method 2: page redirection is adopted. After the user clicks the submit button, it will turn to a new page and prompt the user to submit successfully.
-
Method 3: Use logo, in one session, when the user requests a form, when sending the page on the server can generate a string of cipher text (also can be a random number), follow the page to the client at the same time, when the client fill out the form, click on the submit button, once again the ciphertext is sent back to the server, and compares the cipher and the server, if the same, If they are different, they will not process the business (such as the Internet finance industry mostly adopts this method).
-
Method 4: Using the server-side database, you can add constraints to the tables of the database to prevent repeated commits, but this will increase the database load.
Each of the above four methods has its advantages and disadvantages. We can choose them according to the actual situation of the project or use them in combination.
Reference links; www.jianshu.com/p/5fd07359a… www.cnblogs.com/guozhenqian…