[php] How to prevent the "Confirm Form Resubmission" dialog?

How do I clean information in a form after submit so that it does not show this error after a page refresh?

See image (from chrome):

The dialog has the text:

The page that you're looking for used
information that you entered. Returning to that
page might cause any action you took to be
repeated. Do you want to continue?

I want this dialog not to appear.

This question is related to php javascript jquery codeigniter

The answer is


After processing the POST page, redirect the user to the same page.

On http://test.com/test.php

header('Location: http://test.com/test.php');

This will get rid of the box, as refreshing the page will not resubmit the data.


I was having this problem and added this JavaScript to the bottom of my page (read it at https://www.webtrickshome.com/faq/how-to-stop-form-resubmission-on-page-refresh) and it seemed to work. It seems much simpler a solution. Any drawbacks?

<script>
if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}
</script>

Thanks,

doug


Edit: It's been a few years since I originally posted this answer, and even though I got a few upvotes, I'm not really happy with my previous answer, so I have redone it completely. I hope this helps.


When to use GET and POST:

One way to get rid of this error message is to make your form use GET instead of POST. Just keep in mind that this is not always an appropriate solution (read below).

Always use POST if you are performing an action that you don't want to be repeated, if sensitive information is being transferred or if your form contains either a file upload or the length of all data sent is longer than ~2000 characters.

Examples of when to use POST would include:

  • A login form
  • A contact form
  • A submit payment form
  • Something that adds, edits or deletes entries from a database
  • An image uploader (note, if using GET with an <input type="file"> field, only the filename will be sent to the server, which 99.73% of the time is not what you want.)
  • A form with many fields (which would create a long URL if using GET)

In any of these cases, you don't want people refreshing the page and re-sending the data. If you are sending sensitive information, using GET would not only be inappropriate, it would be a security issue (even if the form is sent by AJAX) since the sensitive item (e.g. user's password) is sent in the URL and will therefore show up in server access logs.

Use GET for basically anything else. This means, when you don't mind if it is repeated, for anything that you could provide a direct link to, when no sensitive information is being transferred, when you are pretty sure your URL lengths are not going to get out of control and when your forms don't have any file uploads.

Examples would include:

  • Performing a search in a search engine
  • A navigation form for navigating around the website
  • Performing one-time actions using a nonce or single use password (such as an "unsubscribe" link in an email).

In these cases POST would be completely inappropriate. Imagine if search engines used POST for their searches. You would receive this message every time you refreshed the page and you wouldn't be able to just copy and paste the results URL to people, they would have to manually fill out the form themselves.

If you use POST:

To me, in most cases even having the "Confirm form resubmission" dialog pop up shows that there is a design flaw. By the very nature of POST being used to perform destructive actions, web designers should prevent users from ever performing them more than once by accidentally (or intentionally) refreshing the page. Many users do not even know what this dialog means and will therefore just click on "Continue". What if that was after a "submit payment" request? Does the payment get sent again?

So what do you do? Fortunately we have the Post/Redirect/Get design pattern. The user submits a POST request to the server, the server redirects the user's browser to another page and that page is then retrieved using GET.

Here is a simple example using PHP:

if(!empty($_POST['username'] && !empty($_POST['password'])) {
    $user = new User;
    $user->login($_POST['username'], $_POST['password']);

    if ($user->isLoggedIn()) {
        header("Location: /admin/welcome.php");
        exit;
    }
    else {
        header("Location: /login.php?invalid_login");
    }
}

Notice how in this example even when the password is incorrect, I am still redirecting back to the login form. To display an invalid login message to the user, just do something like:

if (isset($_GET['invalid_login'])) {
    echo "Your username and password combination is invalid";
}

It has nothing to do with your form or the values in it. It gets fired by the browser to prevent the user from repeating the same request with the cached data. If you really need to enable the refreshing of the result page, you should redirect the user, either via PHP (header('Location:result.php');) or other server-side language you're using. Meta tag solution should work also to disable the resending on refresh.


Quick Answer

Use different methods to load the form and save/process form.

Example.

Login.php

Load login form at Login/index Validate login at Login/validate

On Success

Redirect the user to User/dashboard

On failure

Redirect the user to login/index


You could try using AJAX calls with jQuery. Like how youtube adds your comment without refreshing. This would remove the problem with refreshing overal.

You'd need to send the info necessary trough the ajax call.
I'll use the youtube comment as example.

$.ajax({
    type: 'POST',
    url: 'ajax/comment-on-video.php',
    data: {
        comment: $('#idOfInputField').val();
     },
    success: function(obj) {
        if(obj === 'true') {
            //Some code that recreates the inserted comment on the page.
        }
    }
});

You can now create the file comment-on-video.php and create something like this:

<?php
    session_start();

    if(isset($_POST['comment'])) {
        $comment = mysqli_real_escape_string($db, $_POST['comment']);
        //Given you are logged in and store the user id in the session.
        $user = $_SESSION['user_id'];

        $query = "INSERT INTO `comments` (`comment_text`, `user_id`) VALUES ($comment, $user);";
        $result = mysqli_query($db, $query);

        if($result) {
            echo true;
            exit();
        }
    }
    echo false;
    exit();
?>

This method works for me well and I think the simplest way to do this is to use this javascript code inside the reloaded page's HTML.

_x000D_
_x000D_
if ( window.history.replaceState ) {_x000D_
  window.history.replaceState( null, null, window.location.href );_x000D_
}
_x000D_
_x000D_
_x000D_


I found an unorthodox way to accomplish this.

Just put the script page in an iframe. Doing so allows the page to be refreshed, seemingly even on older browsers without the "confirm form resubmission" message ever appearing.


I had a situation where I could not use any of the above answers. My case involved working with search page where users would get "confirm form resubmission" if the clicked back after navigating to any of the search results. I wrote the following javascript which worked around the issue. It isn't a great fix as it is a bit blinky, and it doesn't work on IE8 or earlier. Still, though this might be useful or interesting for someone dealing with this issue.

jQuery(document).ready(function () {

//feature test
if (!history)
    return;

var searchBox = jQuery("#searchfield");

    //This occurs when the user get here using the back button
if (history.state && history.state.searchTerm != null && history.state.searchTerm != "" && history.state.loaded != null && history.state.loaded == 0) {

    searchBox.val(history.state.searchTerm);

    //don't chain reloads
    history.replaceState({ searchTerm: history.state.searchTerm, page: history.state.page, loaded: 1 }, "", document.URL);

    //perform POST
    document.getElementById("myForm").submit();

    return;
}

    //This occurs the first time the user hits this page.
history.replaceState({ searchTerm: searchBox.val(), page: pageNumber, loaded: 0 }, "", document.URL);

});

It seems you are looking for the Post/Redirect/Get pattern.

As another solution you may stop to use redirecting at all.

You may process and render the processing result at once with no POST confirmation alert. You should just manipulate the browser history object:

history.replaceState("", "", "/the/result/page")

See full or short answers


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to codeigniter

DataTables: Cannot read property 'length' of undefined How to set time zone in codeigniter? php codeigniter count rows CodeIgniter: 404 Page Not Found on Live Server Only variable references should be returned by reference - Codeigniter How to pass a parameter like title, summary and image in a Facebook sharer URL How to JOIN three tables in Codeigniter how to get the base url in javascript How to get id from URL in codeigniter? How to disable PHP Error reporting in CodeIgniter?