web-dev-qa-db-fra.com

Empêcher la resoumission du formulaire en cliquant sur le bouton retour

J'ai cherché de nombreux articles ici et ailleurs, mais je n'arrive pas à trouver une solution à mon problème. J'ai une page qui affiche les entrées de base de données: database.php. Ces entrées peuvent être filtrées avec un formulaire. Lorsque je les filtre et que je n'affiche que ceux qui m'intéressent, je peux cliquer sur une entrée (sous forme de lien) menant à cette page d'entrées (via php GET). Lorsque je suis sur cette page d'entrées ("view.php? Id = 1") et que je clique sur le bouton retour (retour à database.php), le formulaire de filtre nécessite de confirmer la nouvelle soumission du formulaire. Est-il un moyen d'empêcher cela?

voici quelques exemples de code (simplifiés):

Database.php:

<form>
    <select>
        <option>1</option>
        <option>2
        <option>
    </select>
    <input type="submit" name="apply_filter" />
</form>
<?php
if ( isset( $_POST[ "apply_filter" ] ) ) { // display filtered entries
    $filter = $_POST[ "filter" ];
    $q = "Select * from table where col = '" . $filter . "'";
    $r = mysql_query( $q );
} else { // display all entries
    $q = "Select * from table";
    $r = mysql_query( $q );
}
while ( $rec = mysql_fetch_assoc( $r ) ) {
    echo "<a href='view.php?id=" . $rec[ "id" ] . "'>" . $rec[ "name" ] . "</a><br />"; // this is where the link to the view.php page is...
}
?>

Maintenant, comme mentionné, si je clique sur le lien, il me faut "view.php? Id = any". Sur cette page, je viens d'obtenir l'ID de l'URL pour afficher cette entrée unique:

view.php:

<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while (  ) {
    // display entry
}

?>

Si je clique maintenant sur le bouton Précédent, le formulaire sur database.php (celui utilisé pour filtrer les résultats de la base de données) nécessite une confirmation de la resoumission. Non seulement cela est très ennuyant, mais cela m'est aussi inutile.

Comment puis-je réparer cela? J'espère que les exemples de code et l'explication de mon problème sont suffisants. Si ce n'est pas le cas, laissez-moi savoir et je vais essayer de préciser.

20
user1889382

Je sais que cette question est ancienne, mais ayant ce problème moi-même, j'ai découvert deux lignes qui fonctionnent:

header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
23
Ryan Konkolewski

Je sais qu'il y a deux façons de le faire. La manière simple et la manière dure.

Indépendamment de la manière utilisée, lorsque vous traitez avec une page basée sur un état (avec $_SESSION), ce que vous devriez faire pour maintenir vos pages "actives" et sous votre contrôle, empêche la mise en cache de toutes les pages de la manière suivante:

<?php
//Set no caching
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

La difficulté consiste à générer un identifiant et à le stocker quelque part sur la page en tant qu’entrée masquée ou cookie &_SESSION. Ensuite, vous stockez le même identifiant sur le serveur en tant que $_SESSION. S'ils ne correspondent pas, une série d'instructions de type ifelse préprogrammées ne provoque aucun incident lorsque la page est soumise à nouveau (c'est ce qu'elle essaie de faire lorsque vous cliquez en arrière).

Le moyen le plus simple consiste simplement à rediriger l'utilisateur vers la page de soumission du formulaire si celui-ci a été soumis avec succès, comme suit:

header('Location: http://www.mydomain.com/redirect.php');

J'espère que ça aide!

8
Phillip Berger

Une chose qui pourrait aider est que votre formulaire de filtre utilise une méthode GET au lieu de POST.

Les navigateurs empêchent généralement l'entrée POST d'être automatiquement soumise à nouveau, ce qu'ils ne font pas lorsque l'entrée GET est utilisée. En outre, cela permettra aux utilisateurs de créer un lien vers votre page à l'aide d'un filtre.

3
tanios

Une solution alternative qui fonctionne également si/quand la page est rechargée implique de vérifier l'originalité de la publication à l'aide de $ _SESSION. En un mot, recherchez une chaîne unique ou aléatoire.

Dans le formulaire, ajoutez un élément d'entrée avec une valeur définie en utilisant Rand () ou microtime ():

<input type="hidden" name="formToken" value="<?php echo microtime();?>"/>

Et ensuite, encapsulez la fonction PHP pour valider et analyser les données de formulaire dans un bloc if:

if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
       $_SESSION['formToken'] = $_POST['formToken'];
      /*continue form processing */
}
0
SilentStone

J'ai utilisé la réponse à Comment savoir si un utilisateur a accédé à une page en utilisant le bouton Précédent? pour détecter si la visite a été déclenchée par un clic du bouton Précédent du navigateur, puis, le cas échéant, j'ai utilisé JavaScript pour recharger la page. Lorsque la page est rechargée, mon code gère déjà les validations correspondantes pour s'assurer que le formulaire n'est jamais soumis deux fois. L'important dans mon cas était de forcer le rechargement de la page lorsque le formulaire était revisité après avoir cliqué sur le bouton Précédent du navigateur. Ceci est mon code dans l'URL où je voulais appliquer cette validation:

<script type="text/javascript">
    if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
        location.reload();
    }
</script>
0
Jaime Montoya