enviar un formulario GET con parámetros de cadena de consulta y parámetros ocultos desaparecen

231

Considere este formulario:

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

Al enviar este formulario (un formulario GET), los parámetros ayb están desapareciendo. ¿Hay alguna razón para eso? ¿Hay alguna forma de evitar este comportamiento?

Kiquenet
fuente
3
Su elemento de acción está mal formado.
Adrian Godong
No deberían desaparecer, así que creo que necesitaremos ver tu formulario.
UnkwnTech
2
Hola, aquí está el formulario completo, puede crear un HTML con este formulario y ver que los parámetros que paso en la acción están desapareciendo: <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
Por cierto, ¿sabes que te falta una cita final sobre ese valor de acción? Totalmente aparte del problema principal, pero ...
Jay
Publiqué una posible solución usando JavaScript aquí: stackoverflow.com/questions/3548795/…
Jenny O'Reilly

Respuestas:

263

¿No es para eso que los parámetros ocultos son para comenzar ...?

<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>

No contaría con ningún navegador que retenga cualquier cadena de consulta existente en la URL de acción.

Como las especificaciones ( RFC1866 , página 46; HTML 4.x sección 17.13.3) establecen:

Si el método es "get" y la acción es un URI HTTP, el agente de usuario toma el valor de acción, agrega un `? ' a continuación, agrega el conjunto de datos del formulario, codificado con el tipo de contenido "application / x-www-form-urlencoded".

Tal vez uno podría codificar en porcentaje la URL de acción para incrustar el signo de interrogación y los parámetros, y luego cruzar los dedos para esperar que todos los navegadores dejen esa URL como está (y validen que el servidor también la entienda). Pero nunca confiaría en eso.

Por cierto: no es diferente para los campos de formulario no ocultos. Para POST, la URL de acción podría contener una cadena de consulta.

Arjan
fuente
71

En HTML5, este es el comportamiento por especificación.

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

Consulte "4.10.22.3 Algoritmo de envío de formularios", paso 17. En el caso de un formulario GET a un URI http / s con una cadena de consulta:

Deje que el destino sea una nueva URL que sea igual a la acción, excepto que su <query>componente se reemplaza por consulta (agregando un carácter U + 003F QUESTION MARK (?) Si corresponde).

Por lo tanto, su navegador eliminará la parte "? ..." existente de su URI y la reemplazará por una nueva según su formulario.

En HTML 4.01, la especificación produce URI no válidos, aunque la mayoría de los navegadores en realidad no hicieron esto ...

Consulte http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3 , paso cuatro: ¿el URI tendrá un? agregado, incluso si ya contiene uno.

xifoides
fuente
Esto significa: ¿ ?se elimina todo lo que hay detrás de la URL de acción? Entonces, ¿qué es, si el parámetro GET en la url de acción contiene el destino, donde se debe procesar el formulario? gustaría: action="index.php?site=search". No estoy seguro, si poner el parámetro GET en campos de entrada ocultos es una buena idea.
The Bndr
¿Qué quieres decir con especifico @xyphoid?
AmiNadimi
@AmiNadimi: Significa "de acuerdo con la especificación".
recursivo el
14

Lo que puede hacer es usar un foreach simple en la tabla que contiene la información GET. Por ejemplo en php:

foreach ($_GET as $key => $value) {
    echo("<input type='hidden' name='$key' value='$value'/>");
}
Efx
fuente
23
Nota: nunca use este código de ejemplo exactamente como está escrito. Sería muy peligroso. Los valores de GET provienen del usuario, por lo que no deben escribirse en la página sin escapar de ellos primero.
drewm
16
Downvoting hasta que se corrija el error XSS en este código.
spookylukey
1
Esta respuesta proporciona una solución similar pero no vulnerable a XSS.
vvzh
esto no maneja los parámetros de la matriz
Andrew
5

Debe incluir los dos elementos (a y b) como elementos de entrada ocultos, así como C.

Bernhard Hofmann
fuente
Sí, por supuesto que haría esto si fuera posible. Pero digamos que tengo parámetros en la cadena de consulta y en las entradas ocultas, ¿qué puedo hacer?
Creo que su única opción es analizar los pares de nombre / valor de cadena de consulta y producir campos de entrada ocultos. Tal vez si describió un poco más sobre el contexto de la página y la URL, podríamos sugerirle una solución que funcione.
Bernhard Hofmann el
Alternativamente, tome los datos de los elementos de formulario ocultos y agréguelos a la URL y a los parámetros de consulta adicionales, luego reemplace el botón de envío del formulario con un enlace de anclaje simple o un Location:redireccionamiento del servidor si no desea ninguna interacción con el usuario final .
Jason
1

Tuve un problema muy similar en el que para la acción de formulario, tenía algo como:

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

El botón llevaría al usuario al sitio, pero la información de la consulta desapareció, por lo que el usuario aterrizó en la página de inicio en lugar de la página de contenido deseada. La solución en mi caso fue descubrir cómo codificar la URL sin la consulta que llevaría al usuario a la página deseada. En este caso, mi objetivo era un sitio de Drupal, por lo que resultó que /content/somethingtambién funcionó. También podría haber usado un número de nodo (es decir /node/123).

KillerRabbit
fuente
0

Si necesita una solución alternativa, ya que este formulario se puede colocar en sistemas de terceros, puede usar Apache mod_rewrite de esta manera:

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

entonces su nuevo formulario se verá así:

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

y Apache agregará el tercer parámetro a la consulta

wanis
fuente
-3

Tu construcción es ilegal. No puede incluir parámetros en el valor de acción de un formulario. Lo que sucede si intentas esto dependerá de las peculiaridades del navegador. No me sorprendería si funcionara con un navegador y no con otro. Incluso si parecía funcionar, no confiaría en él, porque la próxima versión del navegador podría cambiar el comportamiento.

"Pero digamos que tengo parámetros en la cadena de consulta y en las entradas ocultas, ¿qué puedo hacer?" Lo que puedes hacer es corregir el error. No es para ser sarcástico, pero esto es un poco como preguntar: "Pero digamos que mi URL usa signos de porcentaje en lugar de barras, ¿qué puedo hacer?" La única respuesta posible es que puedes arreglar la URL.

Arrendajo
fuente
Toda esta respuesta es técnicamente correcta ("está mal, así que arréglala") pero no sirve de nada. El OP ya sabe que algo está mal y está preguntando cómo solucionarlo.
Jason
Lo siento, ¿no estuvo claro? "No puede incluir parámetros en el valor de acción de un formulario". Para solucionarlo, elimine los parámetros del valor de acción del formulario.
Jay
@Jay El problema es claramente que el usuario necesita los parámetros de URL para quedarse, por lo que decir "eliminarlos" no va a ayudar
Chuck Le Butt
@ChuckLeButt Decir "pero tengo que hacer esto que no funciona" no es algo útil para decir. Si alguien me dice: "Sigo girando la perilla de la radio pero mi auto no se mueve", la única respuesta que se me ocurre sería decir: "Girar la perilla de la radio no hace que el auto se mueva. Tienes que girar la llave de contacto y pisar el acelerador ". Para responder, "pero necesito hacer que el auto se mueva girando la perilla de la radio" es una respuesta improductiva. No funciona No va a funcionar
Jay
-3

Esto es en respuesta a la publicación anterior de Efx:

Si la URL ya contiene la var que desea cambiar, se agrega nuevamente como un campo oculto.

Aquí hay una modificación de ese código para evitar duplicar vars en la URL:

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

cambie el método de solicitud a 'POST' en lugar de 'GET'.

Shashidhar Gr
fuente
-4

Normalmente escribo algo como esto:

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

¡Esto está funcionando, pero no olvides desinfectar tus entradas contra los ataques XSS!

Rápli András
fuente