botão voltar do navegador restaura campos vazios
-
06-07-2019 - |
Pergunta
Eu tenho um x.php
página web (em uma área protegida por senha do meu web site), que tem uma forma e um botão que utiliza o método POST
para enviar os dados do formulário e abre x.php#abc
. Isso funciona muito bem.
No entanto, se os usuários decide voltar navegar no Internet Explorer 7, todos os campos no x.php
originais são eliminadas e tudo deve ser digitado em novamente. Eu não posso salvar as informações postadas em uma sessão e eu estou tentando compreender como posso obter IE7 para se comportar da maneira que eu quero.
Eu procurei na web e encontrei respostas que sugerem que o cabeçalho HTTP deve conter informações caching explícito. Atualmente, eu tentei isso:
session_name("FOO");
session_start();
header("Pragma: public");
header("Expires: Fri, 7 Nov 2008 23:00:00 GMT");
header("Cache-Control: public, max-age=3600, must-revalidate");
header("Last-Modified: Thu, 30 Oct 2008 17:00:00 GMT");
e suas variações. Sem sucesso. Olhando para os cabeçalhos retornados com uma ferramenta como WireShark me mostra que o Apache é realmente honrar meus cabeçalhos.
Então, minha pergunta é: o que estou fazendo de errado
Solução
IE irá reter conteúdo do formulário em um botão de volta clique automaticamente, desde que:
- você não tenha quebrado cacheing com um pragma no-cache ou similar
- os campos do formulário em questão não foram criadas dinamicamente pelo script
Você parece ter o cacheing na mão, então eu estou supondo que estes últimos podem ser aplicadas. (Como mkoeller diz, Firefox evita este problema se a página estiver nos últimos cliques de volta, mantendo a própria página vivo por mais do que está na tela. No entanto, este é opcional, e Firefox irá reverter para o mesmo comportamento que o IE e outros navegadores Depois de ter navegado algumas páginas adiante e que expirou o antigo.)
Se você estiver criando seus próprios campos do formulário de onload roteiro, em seguida, o navegador tem nenhuma maneira de saber que o novo controle de entrada é 'o mesmo' como o velho exemplo, por isso não pode preenchê-lo com o anteriormente valor -submitted. Neste caso, se você quer jogar bem com o botão de volta você tem que começar a armazenar dados no cliente.
Em seguida, você tem que usar algum tipo de modo que cada conjunto de dados está vinculado a exatamente uma instância da página, caso contrário, passando por várias instâncias do mesmo formulário ou ter dois navegadores abas abertas no formulário ao mesmo tempo digitando estado irá confundir gravemente o seu script.
e então você está começando a coletar uma grande quantidade de dados se eles são grandes formas, e se o mecanismo de armazenamento do lado do cliente que você está usando é cookies que você pode começar a perder dados, como bem como o envio de uma carga do absurdo estado desnecessário com cada solicitação HTTP. Outros mecanismos de armazenamento do lado do cliente estão disponíveis, mas eles específica navegador está.
Em suma: fazer formas geradas dinamicamente bem é uma dor enorme e provavelmente o melhor é evitado se você puder. Tendo forma escondida na página que um script torna visível, permitindo assim que os navegadores para fazer o seu-lembrando campo-magic em vez de dar-lhe a tarefa, é tipicamente muito mais fácil.
Outras dicas
Ao tentar restringir ainda mais o problema, eu encontrei a causa do meu problema. Eu estava a utilizar URLs que estavam a ser reescritas por Apache (isto é, I sempre acedida meu principal como http://foo.com/page
qual é mapeado por Apache para http://foo.com/page.htm
). Usando o real URLs resolveu o problema e fez IE7 feliz, enquanto eu especificar o bom cabeçalho HTTP (Cache-Control
, Expires
, etc.).
Aqui está o que eu faço no código PHP para cabeçalhos de saída que parecem fazer todos os navegadores feliz com o cache:
function emitConditionalGet($timestamp)
{
// See also http://www.mnot.net/cache_docs/
// and code sample http://simonwillison.net/2003/Apr/23/conditionalGet/
$gmdate_exp = gmdate('D, d M Y H:i:s', time() + 1) . ' GMT';
$last_modified = gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
$etag = '"'.md5($last_modified).'"';
// If the client provided any of the if-modified-since or if-none-match
// infos, take them into account:
$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH'])
? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;
if (!$if_modified_since && !$if_none_match)
{
return; // the client does not cache anything
}
if ($if_none_match && $if_none_match != $etag)
{
return; // ETag mismatch: the page changed!
}
if ($if_modified_since && $if_modified_since != $last_modified)
{
return; // if-modified-since mismatch: the page changed!
}
// Nothing changed since last time client visited this page.
header("HTTP/1.0 304 Not Modified");
header("Last-Modified: $last_modified");
header("ETag: $etag");
header("Cache-Control: private, max-age=1, must-revalidate");
header("Expires: $gmdate_exp");
header("Pragma: private, cache");
header("Content-Type: text/html; charset=utf-8");
exit;
}
function emitDefaultHeaders($timestamp)
{
$gmdate_exp = gmdate('D, d M Y H:i:s', time() + 1) . ' GMT';
$last_modified = gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
$etag = '"'.md5($last_modified).'"';
header("Last-Modified: $last_modified");
header("ETag: $etag");
header("Cache-Control: private, max-age=1, must-revalidate");
header("Expires: $gmdate_exp");
header("Pragma: private, cache");
header("Content-Type: text/html; charset=utf-8");
}
function getTimestamp()
{
// Find out when this page's contents last changed; in a static system,
// this would be the file time of the backing HTML/PHP page. Add your
// own logic here:
return filemtime($SCRIPT_FILENAME);
}
// ...
$timestamp = getTimestamp();
emitConditionalGet($timestamp);
emitDefaultHeaders($timestamp); //previously, this variable was mistyped as "$timestaml"
O Firefox faz este tipo de cache. Como eu compreendo a sua pergunta, você quer IE7 se comportar da maneira como o Firefox faz. Eu acho que isso não é possível.
O Firefox e IE7 diferem na maneira de interpretar o botão de volta.
O Firefox irá exibir a árvore DOM da página anterior, uma vez que a última exibida antes que a página foi deixado. Ou seja, todos os dados do formulário ainda será contida no campo de entrada do formulário. Mas você não vai ver um evento onload
após apertar o botão de volta.
IE7 irá processar a página novamente com base na resposta que recebe do servidor. Assim, a forma é emtpy (a menos que houvesse valores padrão enviados pelo servidor originalmente), mas você verá um evento onload
.
Eu picado em torno e isso é um problema difícil. Seu também um grande pé no saco para dinamicamente modificada conteúdo. Você visitar a página, aumenta javascript-lo com sua instrução, você vai para a próxima página e voltar, e javascript esqueceu. E não há nenhuma maneira de simplesmente atualizar do lado do servidor da página, porque a página sai de cache.
Então, eu criei um back-botão-cache-breaker.
Seu mal e mal-for-the-web, mas a torna capaz de páginas para se comportar como as pessoas esperam que eles se comportam em vez de entortar magicamente por todo o lugar.
<script type="text/javascript">//<!-- <![CDATA[
(function(){
if( document.location.hash === "" )
{
document.location.hash="_";
}
else
{
var l = document.location;
var myurl = ( l.protocol + "//" + l.hostname + l.pathname + l.search);
document.location = myurl;
}
})();
//]]> --></script>
Isto irá fazer um pouco de magia em que ele detecta se ou não a página que você está / atualmente / visualização foi carregado a partir do cache ou não.
Se você está lá pela primeira vez, ele irá detectar "não de hash", e acrescentar "#_
" para o URL da página.
se você está lá para o> 1º tempo (isto é: não um link direto para a página), a página já tem o #_ sobre ele, assim que remove-lo e, no processo de removê-lo, desencadeia um recarregamento da página.
Você pode usar autocomplete = "off" em seus campos. Desta forma, os valores não serão armazenados em cache pelo navegador para que os valores não serão preenchidos no formulário quando o usuário clica no botão de volta.