Como impedir o reenvio de formulário quando a página é atualizada (F5 / CTRL + R)
Eu tenho um formulário simples que envia texto para minha tabela SQL. O problema é que, depois que o usuário envia o texto, ele pode atualizar a página e os dados são enviados novamente sem preencher o formulário novamente. Eu poderia redirecionar o usuário para outra página após o envio do texto, mas quero que os usuários permaneçam na mesma página.
Lembro-me de ler algo sobre dar a cada usuário um ID de sessão exclusivo e compará-lo com outro valor que resolveu o problema que estou tendo, mas esqueci onde ele está.
— user701510
Postar / Redirecionar / Obter .
Por que você não deseja redirecionar o usuário para outra página?
@ Adam: Como é um excesso fazer outra solicitação ao servidor que, por sua vez, buscará alguns dados do DB novamente. Mas isso é desperdício de recursos porque nós já buscar todos os dados necessários durante o processamento POSTdo pedido
@EugenKonkov no padrão PRG, você redirecionaria para uma página que mostra uma mensagem de sucesso. Nenhuma busca adicional do DB é necessária.
@ Adam: Você também pode exibir o registro inteiro criado pelos POSTdados. Nesse caso, você precisa SELECTdo DB. Por exemplo, quando você cria a fatura você será redirecionado para /invoices/53o qual exibir toda a factura em vez de apenas 'sucesso'
Use o padrão Publicar / Redirecionar / Obter. http://en.wikipedia.org/wiki/Post/Redirect/Get
Com o meu site, vou armazenar uma mensagem em um cookie ou sessão, redirecionar após a postagem, ler o cookie / sessão e limpar o valor dessa sessão ou variável de cookie.
— Keverw
Isso torna o Chrome inutilizável para o desenvolvimento, onde os negócios exigem apenas uma postagem!
Se você usa o padrão PRG, deixa a página certa? A questão não era como fazer as coisas funcionarem quando não redirecionava?
Parece-me que, se você redirecionar para a mesma página, $ _POST será limpo. Pelo que entendi, esse foi o efeito desejado. Esse era o MEU efeito desejado, de qualquer maneira. Acho que a resposta seria melhor se explicitasse isso.
— Donutguy640 01/05/19
Funciona bem, minha única recomendação é garantir que você ative o rigoroso teste de erros para que você esteja capturando erros localmente durante o desenvolvimento, caso contrário eles poderão passar despercebidos.
Não responde a pergunta. Não sei por que é a resposta aceita.
— YungGun 5/09/19
Gostaria também de salientar que você pode usar uma abordagem de javascript, window.history.replaceStatepara impedir o reenvio no botão Atualizar e Voltar.
Prova de conceito aqui: https://dtbaker.net/files/prevent-post-resubmit.php
Eu ainda recomendaria uma abordagem Post / Redirect / Get, mas esta é uma nova solução JS.
Obrigado, @dtbaker, é :) incrível
Tks, este é um trabalho perfeito para mim, ele só teve que criar página 404 do usuário evitar missunderstanding
— Tess Hsu
Simplesmente incrível. Obrigado
ele não funciona no Safari, ele mudou href mas ainda manter os dados com solicitação post para enviar
— Vo Thanh Tung
Isso funcionou para mim, obrigado! Por que você recomenda a abordagem PRG?
— IJassar 11/11
Você realmente deve usar um padrão Post Redirect Get para lidar com isso, mas se de alguma forma acabou em uma posição em que o PRG não é viável (por exemplo, o próprio formulário está em uma inclusão, impedindo redirecionamentos), você pode usar alguns dos parâmetros de solicitação para criar uma sequência com base no conteúdo e verifique se você ainda não a enviou.
Obrigado por compartilhar, mas isso não parece funcionar. Atualizar a página realmente envia novamente o formulário para mim. Talvez esteja faltando alguma coisa?
A atualização da página reenviará tudo, mas optamos apenas por processar os dados de envio se forem diferentes dos dados enviados na última vez (que armazenamos na sessão var 'messageIdent'). Você está processando o envio do formulário na cláusula 'if messageIdents are different' (ou seja, onde 'do_your_thang ()' está)?
Obrigado pela sua resposta. Acabei implementando o padrão Post / Redirect / Get, então, não me lembro agora do que exatamente estava me incomodando. Mais uma vez obrigado por voltar.
Esse método não visa bloquear o reenvio ... mas Detectar o reenvio, para que você possa alterar seu código para não "fazer" o que você faria se esse fosse um novo envio. Em outras palavras: com esse método, você pode detectar o envio "original" e colocar seus dados. Se NÃO for original, não coloque seus dados. Mostre um aviso de "tentativa de enganar" ou talvez mostre uma "confirmação".
Para que isso funcione, você deve ter iniciado uma sessão adicionando session_start();no início do arquivo. w3schools.com/php/php_sessions.asp diz Nota: A função session_start () deve ser a primeira coisa em seu documento. Antes de qualquer tag HTML.
— wkille
Eu uso essa linha javascript para bloquear o pop-up solicitando o reenvio do formulário na atualização depois que o formulário é enviado.
Basta colocar esta linha no rodapé do seu arquivo e ver a mágica
— Mo'men Mohamed
Seria legal uma versão disso que não pode ser desativada do lado do cliente, mas é curta, fácil, rápida ... e faça o que for necessário. Mantém o histórico para que o usuário possa voltar, sem reenviar a postagem.
— Péter Vértényi 6/02/19
Você pode impedir o reenvio de formulário por meio de uma variável de sessão.
Primeiro você precisa definir rand()em uma caixa de texto e $_SESSION['rand']na página do formulário:
Depois disso, verifique $_SESSION['rand']com o $_POST['randcheck']valor da caixa de texto como este:
— Savoo
podemos usar <input type="hidden" name="randcheck" id="randcheck" value="<?php echo microtime(); ?>" />em vez
— Nikolay Bronskiy
Sim, podemos usar microtime () e time () também em vez de rand (), qualquer função ou variável que dê um valor diferente, podemos usá-lo. MAS certifique-se de definir esse valor para a variável SESSION. aqui SESSÃO é necessário verificar com o campo de verificação aleatória e impedir o reenvio do formulário.
a variável da sessão não deve ser limpa depois de verificar se a sessão e os pós-vars correspondem?
— Denoise # 30/19
@denoise Eu acredito que a idéia do @Savoo é que, após $_POSTos dados do formulário, a mesma página seja recarregada, redefinindo a sessão e postando variáveis. Também a criação de variáveis ​​deve ocorrer após verificar se as variáveis ​​coincidem. Portanto, unsetnão é necessário.
— HalfMen
Quando o formulário é processado, você redireciona para outra página:
você também pode redirecionar para a mesma página.
se você estiver fazendo algo como comentários e quiser que o usuário permaneça na mesma página, use o Ajax para lidar com o envio do formulário
Encontrei a próxima solução alternativa. Você pode escapar do redirecionamento após processar a POSTsolicitação manipulandohistory objeto.
Então você tem o formulário HTML:
Quando você processa este formulário no servidor, em vez de redirecionar o usuário /the/result/page, configure o Locationcabeçalho da seguinte maneira:
Após o processamento dos POSTdados editados, você torna pequeno <script>e o resultado/the/result/page
O <script>que você deve render:
como você pode ver, os dados do formulário são POSTeditados no process.phpscript.
Este script processou POSTdados e renderização de /the/result/pageuma só vez com:
não há POSTdados quando você atualiza a página (F5)
não há POSTquando você navega para a página anterior / seguinte através do histórico do navegador
Como outra solução, peço que o recurso solicite à equipe do Mozilla FireFox que permita aos usuários configurar o NextPagecabeçalho que funcionará como Locationcabeçalho e farápost/redirect/get padrão obsoleto.
Em resumo. Quando o processo do servidor forma POSTdados com êxito, ele:
Configurar NextPagecabeçalho em vez deLocation
Renderize o resultado do processamento de POSTdados do formulário como renderizaria para GETsolicitação no post/redirect/getpadrão
O navegador, por sua vez, quando vê o NextPagecabeçalho:
Ajuste window.locationcomNextPage valor
Quando o usuário atualizar a página, o navegador negociará a GETsolicitação em NextPagevez de reformular os POSTdados
Eu acho que isso seria excelente se implementado, não seria? =)
Use o cabeçalho e redirecione a página.
header("Location:your_page.php"); Você pode redirecionar para a mesma página ou página diferente.
Desmarque $ _POST depois de inseri-lo no banco de dados.
A desativação de $ _POST não afeta o reenvio de formulário, pelo menos não no Chrome.
Isso não vai funcionar. Quando o usuário voltar para a página anterior, execute a configuração das variáveis ​​POST novamente.
Qual o motivo do uso unset? Por favor, adicione alguma explicação à sua resposta para que outras pessoas possam aprender com ela
Uma maneira bastante segura é implementar um ID exclusivo na postagem e armazená-lo em cache no
Então, no seu código, faça o seguinte:
Na verdade, acabei de escrever algo parecido com isso, mas não tive problemas para criar uma senha, apenas enumerei meus formulários (por exemplo: etapas 1 a 5); portanto, se eles são iguais, é legal seguir em frente, caso contrário, não salve em db ou envie e-mails. Mas deixe o usuário chegar onde quer que ele o leve.
Penso que esta é uma solução melhor do que recarregar a página, pois mostro uma mensagem ao publicar com êxito e recarregar a página excluirá a mensagem. esta grelha funciona para mim, você também pode usar um uniqid
— Julio Popócatl
Esse método funciona bem para mim e acho que é o mais simples de fazer esse trabalho.
A idéia geral é redirecionar o usuário para algumas outras páginas após o envio do formulário, o que interromperia o reenvio do formulário na atualização da página. Ainda assim, se você precisar manter o usuário na mesma página após o envio do formulário, poderá fazê-lo de várias maneiras, mas aqui estou descrevendo o método javascript.
Esse método é bastante fácil e bloqueia o pop-up solicitando o reenvio do formulário na atualização assim que o formulário é enviado. Basta colocar esta linha de código javascript no rodapé do seu arquivo e ver a mágica.
— Tanmoy Datta
Isso me ajuda também
Basta redirecioná-lo para a mesma página depois de usar os dados do formulário, e ele funciona. Eu tentei.
— krsoni
Isso está apenas repetindo a mesma resposta que outra pessoa deu anos antes. (Na verdade os outros dois!)
— Nick Rice,
Se você duplicar as respostas de outras pessoas, adicione pelo menos alguma explicação à sua resposta para torná-la interessante
Uma versão refinada da postagem de Moob. Crie um hash do POST, salve-o como um cookie de sessão e compare os hashes a cada sessão.
Basicamente, você precisa redirecionar para fora dessa página, mas isso ainda pode causar problemas enquanto a Internet está lenta (Redirecionar cabeçalho do lado do servidor)
Exemplo de cenário básico:
Clique no botão enviar duas vezes
Maneira de resolver
Desabilitar o botão enviar assim que o cliente clicar nele
Se você estiver usando o Jquery: Jquery.one
Padrão PRG
Usando carimbo de data / hora de hash baseado em diferenciação / carimbo de data / hora quando a solicitação foi enviada.
Use tokens de solicitação. Quando a carga principal for atribuída, atribua uma solicitação temporária que, se repetida, será ignorada.
— ZenithS
Como evitar o reenvio de formulários php sem redirecionar. Se você estiver usando $ _SESSION (após o session_start) e um formulário $ _POST, poderá fazer algo assim:
No seu formulário html, coloque isto:
Portanto, toda vez que o formulário é enviado, um novo ato é gerado, armazenado em sessão e comparado com o ato posterior.
Ps: se você estiver usando um formulário Get, poderá alterar facilmente todo o POST com GET e também funcionará.
Depois de inseri-lo no banco de dados, chame o método unset () para limpar os dados.
não definido ($ _ POST);
Para impedir a inserção de dados de atualização, faça um redirecionamento de página para a mesma página ou página diferente após a inserção do registro.
cabeçalho ('Localização:'. $ _ SERVER ['PHP_SELF']);
— Thinesh
Por favor, adicione alguma explicação à sua resposta para que outras pessoas possam aprender com ela - por que essa unsetligação é necessária? O que aconteceria se você a ignorasse?
Usar o padrão Post / Redirect / Get da resposta do Keverw é uma boa idéia. No entanto, você não consegue permanecer na sua página (e acho que era isso que estava pedindo?) Além disso, às vezes, pode falhar :
Se um usuário da web atualizar antes que o envio inicial seja concluído devido ao atraso do servidor, resultando em uma solicitação HTTP POST duplicada em determinados agentes do usuário.
Outra opção seria armazenar em uma sessão se o texto deveria ser gravado no seu banco de dados SQL como este:
Como já foi dito, não é possível deixar de usar o post / redirecionar / get. Mas, ao mesmo tempo, é muito fácil fazer o que você deseja fazer no lado do servidor.
Na sua página POST, você simplesmente valida a entrada do usuário, mas não age sobre ela; em vez disso, você a copia para uma matriz SESSION. Você então redireciona de volta à página principal de envio novamente. Sua página principal de envio começa verificando se a matriz SESSION que você está usando existe e, em caso afirmativo, copie-a para uma matriz local e desative-a. A partir daí você pode agir sobre isso.
Dessa forma, você realiza todo o seu trabalho principal apenas uma vez, alcançando o que deseja fazer.
Procurei uma solução para evitar o reenvio em um grande projeto posteriormente. O código funciona muito com $ _GET e $ _POST e não posso alterar o comportamento dos elementos do formulário sem o risco de erros imprevistos. Então, aqui está o meu código:
Funciona apenas para evitar o reenvio de $ _POST, não de $ _GET. Mas esse é o comportamento que eu preciso. O problema de reenvio não funciona com uploads de arquivos!
— Andreas Rex
E no seu formulário
— NN73 Player
Este form.phpexemplo mostra como usar o PRG correto (quando o formulário é válido ou não).
Ele redireciona para a mesma página, somente quando o formulário é válido e a ação foi executada.
O redirecionamento impede que o formulário seja reenviado na atualização da página.
Ele usa a sessão para não perder as mensagens de sucesso que você deseja mostrar quando o formulário é válido.
Existem dois botões para teste: "Envio válido", "Envio inválido". Experimente os dois e atualize a página depois disso.
— Oleksii Semeniuk
Por favor, adicione alguma explicação à sua resposta para que outras pessoas possam aprender com ela - de onde $everything_finevem?
Por que não usar a $_POST['submit']variável como uma declaração lógica para salvar o que estiver no formulário. Você sempre pode redirecionar para a mesma página (caso atualizem e quando acessarem go backo navegador, a variável de envio não será mais definida. Verifique se o botão de envio tem um namee idde submit.