o envio de um formulário GET com parâmetros de cadeia de consulta e parâmetros ocultos desaparecem

231

Considere este formulário:

<form action="http://www.blabla.com?a=1&b=2" method="GET">
    <input type="hidden" name="c" value="3" /> 
</form>

Ao enviar este formulário (um formulário GET), os parâmetros aeb estão desaparecendo. Existe uma razão para isso? Existe uma maneira de evitar esse comportamento?

Kiquenet
fonte
3
Seu elemento de ação está incorreto.
Adrian Godong
Eles não devem desaparecer, então acho que precisamos ver sua forma.
UnkwnTech 12/07/2009
2
Olá, Aqui está o formulário completo, você pode apenas criar um HTML com este formulário e ver se os parâmetros que eu passo na ação estão desaparecendo: <form action = " example.com?e=4&f=5 " method = "GET"> <input type = "hidden" name = "a" value = "1" /> <input type = "hidden" name = "b" value = "2" /> <input type = "hidden" name = "c" value = "3" /> <input type = "submit" /> </form>
1
A propósito, você sabe que está faltando uma cotação final nesse valor da ação? Totalmente além da questão principal, mas ...
Jay
Eu postei uma possível solução alternativa usando JavaScript aqui: stackoverflow.com/questions/3548795/...
Jenny O'Reilly

Respostas:

263

Não é para isso que servem os parâmetros ocultos ...?

<form action="http://www.example.com" method="GET">
  <input type="hidden" name="a" value="1" /> 
  <input type="hidden" name="b" value="2" /> 
  <input type="hidden" name="c" value="3" /> 
  <input type="submit" /> 
</form>

Eu não contaria com nenhum navegador mantendo nenhuma string de consulta existente no URL da ação.

Conforme as especificações ( RFC1866 , página 46; seção 17.13.3 do HTML 4.x ):

Se o método for "get" e a ação for um URI HTTP, o agente do usuário pegará o valor da ação e anexará um `? ' a ele, em seguida, anexa o conjunto de dados do formulário, codificado usando o tipo de conteúdo "application / x-www-form-urlencoded".

Talvez alguém possa codificar por cento o URL da ação para incorporar o ponto de interrogação e os parâmetros e depois cruzar os dedos para esperar que todos os navegadores deixem esse URL como ele (e validam que o servidor também o entende). Mas eu nunca confiaria nisso.

A propósito: não é diferente para campos de formulário não ocultos. Para POST, o URL da ação pode conter uma string de consulta.

Arjan
fonte
71

No HTML5, esse é um comportamento por especificação.

Consulte http://www.w3.org/TR/2011/WD-html5-20110525/association-of-controls-and-forms.html#form-submission-algorithm

Veja "4.10.22.3 Algoritmo de envio de formulário", etapa 17. No caso de um formulário GET para um URI http / s com uma string de consulta:

Permita que o destino seja um novo URL igual à ação, exceto que seu <query>componente seja substituído pela consulta (adicionando um caractere U + 003F QUESTION MARK (?), Se apropriado).

Portanto, seu navegador lixeira a parte "? ..." existente do seu URI e a substitui por uma nova com base em seu formulário.

No HTML 4.01, a especificação produz URIs inválidos - a maioria dos navegadores ainda não fez isso.

Consulte http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3 , etapa quatro - o URI terá um? anexado, mesmo que já contenha um.

xifóide
fonte
isso significa: tudo o que está por trás do ?URL de ação é removido? Então, o que é, se o parâmetro GET no URL da ação contiver o destino, onde o formulário deve ser processado? gosto: action="index.php?site=search". Não tenho certeza, se colocar o parâmetro GET em campos de entrada ocultos é uma ideia divina.
The Bndr
o que você quer dizer com @xyphoid por especificação?
AmiNadimi
@AmiNadimi: Significa "de acordo com a especificação".
recursivo
14

O que você pode fazer é usar um foreach simples na tabela que contém as informações GET. Por exemplo, em php:

foreach ($_GET as $key => $value) {
    echo("<input type='hidden' name='$key' value='$value'/>");
}
Efx
fonte
23
Nota: nunca use este código de exemplo exatamente como está escrito. Seria muito perigoso. Os valores de GET vêm do usuário, portanto, não devem ser gravados na página sem escapá-los primeiro.
drewm
16
Voto negativo até que o bug do XSS neste código seja corrigido.
Spookylukey
1
Esta resposta fornece uma solução semelhante, mas não é indiferente ao XSS.
vvzh
isso não lidar com parâmetros de matriz
Andrew
5

Você deve incluir os dois itens (a e b) como elementos de entrada ocultos e também C.

Bernhard Hofmann
fonte
Sim, é claro que eu faria isso se possível. Mas digamos que eu tenha parâmetros na string de consulta e nas entradas ocultas, o que posso fazer?
Acho que sua única opção é analisar os pares nome / valor da string de consulta e produzir campos de entrada ocultos. Talvez se você descreveu um pouco mais sobre o contexto da página e do URL, poderemos sugerir uma solução funcional.
Bernhard Hofmann
Como alternativa, pegue os dados dos itens ocultos do formulário e adicione-os à URL e aos parâmetros de consulta adicionais e substitua o botão de envio do formulário por um link âncora simples ou um Location:redirecionamento do servidor, se você não desejar nenhuma interação com o usuário final. .
28418 Jason
1

Eu tive um problema muito semelhante ao da ação do formulário, algo como:

<form action="http://www.example.com/?q=content/something" method="GET">
   <input type="submit" value="Go away..." />&nbsp;
</form>

O botão levaria o usuário ao site, mas as informações da consulta desapareceram para que o usuário chegasse à página inicial em vez da página de conteúdo desejada. A solução no meu caso foi descobrir como codificar a URL sem a consulta que levaria o usuário à página desejada. Nesse caso, meu alvo era um site do Drupal, pelo que /content/somethingtambém funcionou. Eu também poderia ter usado um número de nó (ie /node/123).

KillerRabbit
fonte
0

Se você precisar de uma solução alternativa, como esse formulário pode ser colocado em sistemas de terceiros, use o Apache mod_rewrite da seguinte maneira:

RewriteRule ^dummy.link$ index.php?a=1&b=2 [QSA,L]

seu novo formulário ficará assim:

<form ... action="http:/www.blabla.com/dummy.link" method="GET">
<input type="hidden" name="c" value="3" /> 
</form>

e o Apache anexará o terceiro parâmetro à consulta

wanis
fonte
-3

Sua construção é ilegal. Você não pode incluir parâmetros no valor da ação de um formulário. O que acontece se você tentar isso dependerá das peculiaridades do navegador. Eu não ficaria surpreso se funcionasse com um navegador e não com outro. Mesmo que parecesse funcionar, eu não confiaria nele, porque a próxima versão do navegador pode mudar o comportamento.

"Mas digamos que eu tenha parâmetros na string de consulta e nas entradas ocultas, o que posso fazer?" O que você pode fazer é corrigir o erro. Para não ser brincalhão, mas isso é um pouco como perguntar: "Mas digamos que meu URL use sinais de porcentagem em vez de barras, o que posso fazer?" A única resposta possível é que você pode corrigir o URL.

Jay
fonte
Toda essa resposta é tecnicamente correta ("está errada, então conserte"), mas não serve para nada. O OP já sabe que algo está errado e está aqui perguntando como consertá-lo.
28418 Jason
Me desculpe, não estava claro? "Você não pode incluir parâmetros no valor da ação de um formulário." Para corrigi-lo, remova os parâmetros do valor da ação do formulário.
Jay
@Jay O problema é claramente que o usuário precisa os parâmetros de URL para ficar, assim dizendo "removê-los" não vai ajudar
Chuck Le bumbum
@ChuckLeButt Dizer "mas preciso fazer algo que não funcione" não é algo útil de se dizer. Se alguém me disser: "Eu continuo girando o botão do rádio, mas meu carro não se move", a única resposta que consigo pensar seria dizer: "Girar o botão do rádio não faz o carro se mover. Você precisa girar. a chave da ignição e pressione o pedal do acelerador ". Responder: "mas preciso fazer o carro girar o botão do rádio" é uma resposta improdutiva. Isso não funciona. Isso não vai funcionar.
Jay
-3

Isso é uma resposta à postagem acima da Efx:

Se o URL já contiver o var que você deseja alterar, ele será adicionado novamente como um campo oculto.

Aqui está uma modificação desse código para impedir a duplicação de vars no URL:

foreach ($_GET as $key => $value) {
    if ($key != "my_key") {
        echo("<input type='hidden' name='$key' value='$value'/>");
    }
}
º_
fonte
-4
<form ... action="http:/www.blabla.com?a=1&b=2" method ="POST">
<input type="hidden" name="c" value="3" /> 
</form>

altere o método de solicitação para 'POST' em vez de 'GET'.

Shashidhar Gr
fonte
-4

Eu costumo escrever algo como isto:

foreach($_GET as $key=>$content){
        echo "<input type='hidden' name='$key' value='$content'/>";
}

Isso está funcionando, mas não se esqueça de higienizar suas entradas contra ataques XSS!

Rápli András
fonte