Evitar a reapresentação do formulário ao carregar no botão para trás
procurei em muitos lugares aqui e em outros lugares, mas não consigo encontrar uma solução para o meu problema. Eu tenho uma página que mostra entradas de banco de dados: banco de dados.pai. Estas entradas podem ser filtradas com um formulário. Quando os filtro e só exibo os que me interessam, posso clicar numa entrada (como um link) que me leva a essa página de entradas (via php GET). Quando estou nessa página de entradas (i.e., " ver.php?id=1") e carregue no botão de trás (voltar à base de dados.php), a forma de filtro necessita de confirme o formulário de reapresentação. Há alguma maneira de evitar isto?
Aqui estão alguns exemplos de códigos (simplificados):
Base de dados.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...
}
?>
agora como mencionado, Se eu clicar no link, Ele me leva a " ver.php?id=whatever". Nessa página, só consigo o ID do url para mostrar esse único item:
Vista.php:
<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while ( ) {
// display entry
}
?>
Se agora carregar no botão de trás, no formulário da base de dados.php (o usado para filtrar os resultados DB) requer confirmação para reenvio. Não só é muito irritante, como também é inútil para mim.
Como posso resolver isto? Espero que os exemplos de código e a explicação do meu problema sejam suficientes. Se não me avisares, vou tentar especificar.
5 answers
Sei que esta pergunta é antiga, mas tendo este problema eu mesmo, duas linhas que descobri que funcionam são:
header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
Independentemente do caminho, quando você está lidando com uma página baseada no estado (usando $_SESSION
), que você deve estar fazendo para manter suas páginas "ao vivo" e sob seu controle, é evitar o caching de todas as páginas como este:
<?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");
?>
A maneira difícil envolve gerar um id e armazená-lo algures na página como uma entrada escondida ou um cookie {[[3]}. Então você armazena o mesmo id no servidor que um $_SESSION
. Se eles não coincidam, uma série de pré-programados.if
else
As declarações de tipo fazem com que nada aconteça com a página seja reenviado (que é o que ele tenta fazer quando você clicar de volta).
A forma mais fácil é simplesmente redireccionar o utilizador de volta para a página de envio do formulário se o formulário foi enviado com sucesso, como por exemplo:
header('Location: http://www.mydomain.com/redirect.php');
Espero que isto ajude!
Uma coisa que pode ajudar é fazer com que a sua forma de filtro use um método GET
em vez de POST
.
Os navegadores normalmente impedem POST
a entrada de ser automaticamente submetida de novo, O que é algo que eles não fazem quando GET
a entrada é usada. Além disso, isso permitirá que os usuários link para a sua página usando um filtro.
Uma solução alternativa que também funciona se/quando a página é recarregada envolve verificar a originalidade do post usando $_SESSION. Em poucas palavras, verifique se existe uma cadeia única ou aleatória.
Na forma, adicione um elemento de entrada com um conjunto de valores usando rand () ou microtime ():
<input type="hidden" name="formToken" value="<?php echo microtime();?>"/>
E depois mudar a função PHP para validar e processar os dados do formulário num bloco if:
if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
$_SESSION['formToken'] = $_POST['formToken'];
/*continue form processing */
}
Você precisa remover o pedido que POST
Dados do histórico do navegador
history.replaceState("", "", "/the/result/page")
Ver esta resposta
Também pode seguir o Post/Redirect/Get
padrão.