How do I stop the Back and Refresh buttons from resubmitting my form?
Asked Answered
E

13

27

I am doing web development.

I have a page to do with credit card, which when user click "refresh" or "Back", the transaction will be performed one more time, which is unwanted.

This include Browser top left "Back" & "Refresh" button, "right click->Refresh/Back", press "F5" key. This is to be done on certain cgi page only, not all of them.

Can this be done using Javascript? Or any other method?

Egis answered 20/3, 2009 at 9:1 Comment(0)
T
51

The standard way is to do it in 3 steps.

  1. the form page submits fields to processing page
  2. processing page processes data and redirects to result page
  3. result page just displays results, reloading it won't do any harm.
Tenrec answered 20/3, 2009 at 9:3 Comment(8)
Also known as the Post-Redirect-Get pattern.Skylar
This doesn't stop the form from being reprocessed if the user hits "Back" (if they tell their browser to resubmit)Bindweed
@philfreo- actually, it does prevent it. Most frameworks today will issue a "302 Moved" header, which effectively tells the browser to use the results page for the history during back-button navigation.Basaltware
What about in Single Page Applications, where somebody posted to your app ?Ileum
@jamiebarrow: in SPA you'd use AJAX calls to submit forms.Tenrec
@Tenrec You're misunderstanding me, I mean if someone else does a form post to the SPA. For example, a separate payment gateway system that you don't have control over. Asked question here - #19136015Ileum
If you use a HTTP POST to submit the transaction most browsers warn you that you will be resubmitting the form when you press the back button. It helps prevent the user pressing the back button somewhat. #16091567Ninebark
is there any way if I can tell whether a page is implemented like this? The page I am looking at showed a warning about clicking "Back" but not refresh. That would fit with this answer... But when I tried refresh, my browser warned me "The page that you're looking for used information that you entered. Returning to that page might cause any action that you took to be repeated. Do you want to continue?"Signification
P
12

This breaks the basic browser user experience model...users should always be able to use the Refresh and Back buttons in their browser. Recommend that you fix your page another way.

If you update your question to include the server language/platform/technology that you are using then someone might be able to suggest a solution.

Picker answered 20/3, 2009 at 9:15 Comment(0)
M
9

The simple fact that resubmitting the form generates a duplicate transaction is worrying. You should have some sort of check to ensure each submit of form data is unique.

For example, the page which would submit the form should be given a unique ID that gets submitted with the form. The business logic should then be able to recognise that the form submitted has already been processed (as the (no longer) unique ID will be the same), so ignores the second attempt.

The 'standard way' still doesn't stop clients from clicking the back button twice... or even going back and resubmitting the form if they don't think (for whatever reason) it has been processed.

Mycenae answered 20/3, 2009 at 9:20 Comment(0)
V
7
  1. generate a random string and store it in session,

  2. then output it to your form as a hidden value,

  3. check the submitted and store variable, if matches process your request,

  4. go to 1.

Veronicaveronika answered 8/8, 2012 at 12:47 Comment(1)
What do you mean by "store value"?Bleed
C
3

Place this code on the form page

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Response.Cache.SetExpires(DateTime.Now-new TimeSpan(1,0,0));

Response.Cache.SetLastModified(DateTime.Now);

Response.Cache.SetAllowResponseInBrowserHistory(false);
Conspicuous answered 8/5, 2009 at 1:37 Comment(2)
What is this code supposed to do ? Expire the page when user hits back button ?Baltic
+1 That is c# code that will make the browser give a "Page Expired" warning if a user tries to click "Back" on their browserSoapy
P
2

You shouldn't try to "block" these actions. What you should do is make sure that nothing happends when someone "double submits" the form.

Promethium answered 20/3, 2009 at 9:18 Comment(0)
H
1

and in some browser you can´t even do that, and this is good!

Hyo answered 20/3, 2009 at 9:20 Comment(0)
P
1

The best way is to have enough session handling logic that you can recognise the 2nd (and onwards) attempt as "this is just a re-submission" and ignore it.

Pulpy answered 20/3, 2009 at 9:21 Comment(0)
S
1

I didn't see this here so here it is.

  1. Put a unique token in the form.
  2. The submit button triggers an xmlhttp(ajax) request to the server to create a session variable named after the token with a stored value of 1.
  3. The ajax request submits the form after receiving a positive state change.
  4. The form processing script checks for the session variable withe the stored value of 1.
  5. The script removes the session variable and processes the form.

If the session variable is not found, the form will not be processed. Since the variable is removed as soon as its found, the form can only be run by pressing the submit button. Refresh and back will not submit the form. This will work without the use of a redirect.

Sjoberg answered 22/5, 2014 at 23:59 Comment(0)
M
0

vartec:s solution solves the reload-problem, not the back-problem, so here are a solution to that:

  1. The form page sets a session variable, for example session("fromformpage")=1
  2. The processing page check the session variable, if its ="1" then process data and redirect to result page if any other than ="1" then just redirect to result page.
  3. The result page sets the session variable to "".

Then if the user is pressing back button, the processing page will not do the process again, only redirect to process page.

Metamorphosis answered 20/3, 2009 at 9:16 Comment(2)
Back button wouldn't take you to processing page anyways. It'll take you directly to form page.Tenrec
still, its a problem that has to be taken care of.Metamorphosis
L
0

I found the above Post/Redirect/Get explanations a little ambiguous

Here's what I followed and hopefully it helps someone in the future

http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html

Essentially the process based on the above solution is:

  1. Submit from the FORM page to the processing page (or to itself)
  2. Handle database or payment processing etc
  3. If required, store user feedback message in a session variable, possible error messages etc
  4. Perform header redirect to results page (or to original form page). If required, display custom message from processing page. Such as "Error Credit Card payment was rejected", and reset session variables.

Redirect with something like:

header("HTTP/1.1 303 See Other");
header("Location: http://$_SERVER[HTTP_HOST]/yourfilehere.php");
die();

The header redirect will initiate a GET request on "yourfilehere.php", because a redirect is simply that, a "request" to fetch data FROM the server, NOT a POST which submits data TO the server. Thus, the redirect/GET prevents any further DB/payments processing occurring after a refresh. The 301 error status will help with back button pressing.

Helpful Reading:

  1. http://en.wikipedia.org/wiki/URL_redirection#HTTP_status_codes_3xx
  2. http://www.theserverside.com/news/1365146/Redirect-After-Post
  3. http://wordsideasandthings.blogspot.ca/2013/04/post-redirect-get-pattern-in-php.html
  4. https://en.wikipedia.org/wiki/HTTP#Request_methods
  5. http://en.wikipedia.org/wiki/Post/Redirect/Get
Levitical answered 22/11, 2013 at 1:21 Comment(0)
H
0

Just put this javascript on the html section of aspx page above head section

<script type = "text/javascript" >
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
</script>

We need to put it on the html section of the page which we want to prevent user to visit by hitting the back button

Complete code of the page looks like this

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type = "text/javascript" >
function disableBackButton()
{
window.history.forward();
}
setTimeout("disableBackButton()", 0);
</script>
</head>
<body onload="disableBackButton()">
<form id="form1" runat="server">
<div>
This is First page <br />
<br />
Go to Second page
<br />
<br />
<asp:LinkButton ID="LinkButton1" runat="server"
PostBackUrl="~/Default2.aspx">Go to Second Page
</asp:LinkButton></div>
</form>
</body>
</html>

If you are using firefox then use instead of onload

If you want to disable back button using code behind of aspx page,than you need to write below mentioned code C# code behind

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string strDisAbleBackButton;
strDisAbleBackButton = "<script language="javascript">\n";
strDisAbleBackButton += "window.history.forward(1);\n";
strDisAbleBackButton += "\n</script>";
ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "clientScript", strDisAbleBackButton);
} 

We can also achieve this by disabling browser caching or cache by writing this line of code either in Page_load event or in Page_Init event

protected void Page_Init(object Sender, EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(DateTime.Now.AddSeconds(-1));
Response.Cache.SetNoStore();
}

Doing this,user will get the page has expired message when hitting back button of browser

Demo is :

enter image description here

Hoatzin answered 17/12, 2013 at 10:21 Comment(0)
H
0

This code works for not back from current page me..

Here I put a code which helps you , not open contextmenu and on browser reload ask you leave a page or not...

I am trying the ask click on browser back button

jQuery( document ).ready(function() {

    document.onkeydown = fkey;
    document.onkeypress = fkey
    document.onkeyup = fkey;

    var wasPressed = false;

    function fkey(e){
        e = e || window.event;
        //alert(e.keyCode);
        if( wasPressed ) return; 


        if (e.keyCode == 116 || e.keyCode == 8 || e.keyCode == 17) {
                     // alert("f5 pressed");
                      window.onbeforeunload = null;
                      return true;
                 }

    }
window.onbeforeunload = function (event) {
    var message = ''; // Type message here

    if (typeof event == 'undefined') {
        event = window.event;
    }
    if (event) {
        event.returnValue = message;
    }

    return message;
};

jQuery(function () {

    jQuery("a").click(function () {
        window.onbeforeunload = null;
    });

    jQuery(".btn").click(function () {
        window.onbeforeunload = null;
    });

    //Disable part of page
    $(document).on("contextmenu",function(e){
        return false;
    });
});});

Thanks,

Heliopolis answered 25/7, 2014 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.