9

I am in bit of a delicate situation here. In my organization we design stock management systems and it is a web application based on JSP pages and servlets which handles them.

I have been asked to fix a specific problem. We have a JSP page with an HTML form table where there are stock details. When user enters the details manually and submit the form, stock details updated in the database and it works fine.

Problem is this : When the user press the browser's back button, user can come to the previous page where he submitted the details. And when the user submit this, data is saved once more to the database.I need to prevent this behaviour.(Something likeclear and reload the page.)

Things I did so far : clear the browser cache.Code works fine but not the expected result.

Unfortunately I cannot share the code due to company regulations. What I need is a help to prevent this behaviour or a workaround.

Thanks in advance..

szczepanpp
  • 809
  • 8
  • 12
Lucy Ferrier
  • 202
  • 1
  • 2
  • 11
  • 1
    I understand you can't share exact code, but is there a way you could generalize your code to make it not company specific? – Michael Sep 12 '17 at 19:33
  • I am sorry Michael but it is a complex code and I do not know what are the relevant parts that you want. Thanks for the reply. – Lucy Ferrier Sep 13 '17 at 15:25

6 Answers6

7

You can use a javascript function with the help of a hidden attribute to reload the web page. When the user press the back button,based on the value of the hidden attribute, page will be reloaded without loading the cached page.

Your approach of clearing cache is correct. Coupled with that, you can use this approach.

<input type="hidden" id="refreshed" value="no">
    <script type="text/javascript">

           onload=function(){
               var e=document.getElementById("refreshed");
               if(e.value=="no")e.value="yes";
               else{e.value="no";location.reload();}
           }

    </script>

One drawback of this approach is if your clients' browsers have disabled JS, this will not work.Otherwise it should work.

Supun Amarasinghe
  • 1,443
  • 3
  • 12
  • 24
4

You must use a Post-Redirect-Get pattern: https://en.m.wikipedia.org/wiki/Post/Redirect/Get.

Actually, every use of standard HTML forms with method="post" should be implemented with that pattern. It doesn't have any use for AJAX-posted forms, which actually could be another solution but will require more work and probably some architectural changes.

szczepanpp
  • 809
  • 8
  • 12
  • Thanks for the suggestion and the resource. But I am afraid I will not be allowed to do dramatic changes to the already existing code. Anyway I will try to explain to my superiors if nothing else works out :) – Lucy Ferrier Sep 13 '17 at 15:29
  • 1
    Actually, it should be pretty straight-forward. For an invalid input you don't change anything - user will see a page with rendered error messages and if he resubmits the form - it'll just display the same validation errors. For a successful submit though, you perform a redirect instead of rendering a page. It's a good practice to redirect to a confirmation page, so user knows that his action really succeeded (probably an additional work in your case) but you could also simply redirect to the same page. – szczepanpp Sep 13 '17 at 15:49
4

When the user press the browser's back button, user can come to the previous page where he submitted the details. And when the user submit this, data is saved once more to the database.

According to how you described it, that is based on a doGet request. Which means every time you visit that URL, it will send the request with whatever parameters were added.

As someone already mentioned, if you switch the form to a post method and switch the Servlet to a doPost, you won't have this issue anymore.

Alternatively you can circumvent this with a javascript solution. Here are some options:

Jonathan Laliberte
  • 2,672
  • 4
  • 19
  • 44
  • 1
    Same thing happens to me on a `POST` form in Firefox on Android 6. You get back to the page with a form and it is already populated so you can submit it again. – szczepanpp Sep 13 '17 at 00:56
  • 1
    Thanks Jonathan I will try your suggestion and let you know the results. – Lucy Ferrier Sep 13 '17 at 15:27
3

You can use this code also

$(document).ready(function() {
    function disableBack() { window.history.forward() }

    window.onload = disableBack();
    window.onpageshow = function(evt) { if (evt.persisted) disableBack() }
});
Tobias Theel
  • 3,088
  • 2
  • 25
  • 45
Romi
  • 31
  • 2
1

I had this same problem while building a django web app, and my solution was to not allow caching of the html that contains the form. In your request handler, do not allow the browser to cache the page. This will force the browser to get the page fresh from the document.

Which, in this case, you can just verify in your request handler if the requested form has already been submitted.

My code for reference:

from django.views.decorators.cache import never_cache
    @never_cache
      def GetForm(request, pk):
          # Logic #
          if (IsFormCompleted(pk)):
             # Handle request #
desertnaut
  • 57,590
  • 26
  • 140
  • 166
1

Here is a solution.

give a random id in a hidden field on the form. Then on the server side, if the user resubmit, check if the random id already on the database. If so, redirect user.

Ken Xu
  • 11
  • 2