¿Es una buena práctica usar una URL vacía para el atributo de acción de un formulario HTML? (acción = "")

279

Me pregunto si alguien puede dar una respuesta de "mejores prácticas" al uso de acciones de formulario HTML en blanco para volver a publicar en la página actual.

Hay una publicación que pregunta qué hace una acción de formulario HTML en blanco aquí y algunas páginas como esta sugieren que está bien, pero me gustaría saber qué piensa la gente.

Matt Mitchell
fuente
77
Se sugiere aplicar la etiqueta "mejores prácticas" a esto.
Will Morgan
Para confirmar doblemente, deje la acción en blanco, o simplemente no mencione ninguna acción (como <form name="xyz" >). Presentará la acción por sí solo.
lwpro2
11
Si no se incluye el atributo de acción, la página se abre a los ataques de clickjacking de iframe , como uno en el que un atacante envuelve su página en un iframe y la URL del iframe incluye un parámetro de consulta con el mismo nombre que un campo de formulario. Cuando se envía el formulario, el valor de la consulta se inserta en la base de datos, por lo que la información de identificación del usuario (correo electrónico, dirección, etc.) se ha visto comprometida.
Paul Sweatte
Entonces, ¿cuál es la forma válida y segura de enviar un formulario a la página actual?
Costa

Respuestas:

268

Lo mejor que puede hacer es dejar de lado el atributo de acción. Si lo deja fuera, el formulario se enviará a la dirección del documento, es decir, a la misma página.

También es posible dejarlo vacío, y cualquier navegador que implemente el algoritmo de envío de formularios HTML lo tratará como equivalente a la dirección del documento, lo que hace principalmente porque así es como funcionan actualmente los navegadores:

8.Deje que la acción sea la acción del elemento remitente .

9.Si action es la cadena vacía, deje que action sea la dirección del documento .

Nota: Este paso es una violación intencional de RFC 3986, que requeriría el procesamiento de URL base aquí. Esta violación está motivada por un deseo de compatibilidad con contenido heredado. [RFC3986]

Esto definitivamente funciona en todos los navegadores actuales, pero puede no funcionar como se esperaba en algunos navegadores más antiguos ( "los navegadores hacen cosas raras con una acción vacía =" "atributo " ), por lo que la especificación desalienta fuertemente a los autores a dejarlo vacío :

Los atributos de contenido actiony formaction, si se especifican, deben tener un valor que sea una URL no vacía válida potencialmente rodeada de espacios .

mercator
fuente
12
Posiblemente esto ha cambiado desde su respuesta (han pasado casi tres años), pero a partir de hoy, HTML5 no permite action=""—ver mi respuesta ...
derobert
2
@derobert Gracias. Esto probablemente no había cambiado. He cambiado mi respuesta para reflejar mejor lo que dice la especificación.
mercator
73

En realidad, la subsección de envío de formularios del borrador HTML5 actual no permite action="". Está en contra de la especificación.

Los atributos de contenido actiony formaction, si se especifican, deben tener un valor que sea una URL no vacía válida potencialmente rodeada de espacios. (énfasis añadido)

La sección citada en la respuesta de mercator es un requisito para las implementaciones , no para los autores . Los autores deben seguir los requisitos del autor. Para citar cómo leer esta especificación :

En particular, existen requisitos de conformidad que se aplican a los productores, por ejemplo, los autores y los documentos que crean, y hay requisitos de conformidad que se aplican a los consumidores, por ejemplo, los navegadores web. Se pueden distinguir por lo que requieren: un requisito para un productor establece lo que está permitido, mientras que un requisito para un consumidor establece cómo debe actuar el software.

El cambio de HTML4, que permitió una URL vacía, se realizó porque "los navegadores hacen cosas raras con un action=""atributo vacío ". Teniendo en cuenta la razón del cambio, probablemente sea mejor no hacerlo tampoco en HTML4.

derobert
fuente
¿Permite la ausencia total del actionatributo por completo para indicar que el formulario debe enviarse a la dirección del documento? Parece que, como dice, "si se especifica".
Kerrick
2
@Kerrick Sí, creo que HTML5 permite omitir el atributo de acción por completo, y lo predetermina a una cadena vacía. HTML4 no lo hizo, especifica la acción según sea necesario.
derobert 01 de
Estoy de acuerdo con @Kerrick, está permitido omitir el atributo de acción. Leyendo en el dibujo HTML5 actual, parece que no se permite una cadena vacía pero se permite la ausencia del atributo. Pero, en cualquier caso, por razones de compatibilidad, le recomiendo que siempre incluya el atributo "acción" y lo complete con una URL válida no vacía (las buenas prácticas son siempre la mejor manera).
serfer2
Un problema potencial: AngularJS evitará el envío de formularios sin un atributo de acción. Probablemente no sea un problema común, pero me tomó un tiempo descubrir por qué partes de nuestro sitio heredado comenzaron a romperse.
Asmor
18

No incluir el atributo action abre la página a los ataques de clickjacking de iframe , que implican unos simples pasos:

  • Un atacante envuelve tu página en un iframe
  • La URL del iframe incluye un parámetro de consulta con el mismo nombre que un campo de formulario
  • Cuando se envía el formulario, el valor de la consulta se inserta en la base de datos
  • La información de identificación del usuario (correo electrónico, dirección, etc.) se ha visto comprometida

Referencias

Paul Sweatte
fuente
2
¿La URL del iframe no contiene parámetros GET, mientras que los formularios generalmente se envían usando POST? Entonces, si el sitio solo trata con los parámetros POST, entonces no debería ser un problema, ¿no? Al menos, generalmente uso la matriz $ _POST en PHP solo cuando proceso formularios.
Calmarius
2
@ Calmarius Sí, use en $_POSTlugar de $_REQUESTpara evitar esto. Si utiliza el código marco $_REQUEST, use un bloqueador de marcos flotantes .
Paul Sweatte
17

Esto se validará con HTML5.

<form action="#">

fuente
44
No lo he probado, pero conceptualmente, ¿no se desplazaría hasta la parte superior de la página después del envío?
Matt Mitchell
2
¿No podrías usar action="."?
s427
3
acción = "?" Funciona bien también. Valida y apunta a la página actual sin y consulta datos de cadena.
Chris Broski
55
action="."Es una mala idea para el caso general. Una URL como example.com/loginse asigna a meramente example.com/.
Torsten Bronger
1
Esta respuesta solo es válida si el usuario desea desplazarse a la parte superior de la página.
Buts
9

EN HTML 5 action=""NO ES SOPORTADO, NO HAGA ESTO. MALA PRÁCTICA.

Si, en cambio, niega por completo la acción, se enviará a la misma página de forma predeterminada, creo que esta es la mejor práctica:

<form>This will submit to the current page</form>

Si está enviando el formulario usando php, puede considerar lo siguiente. Lea más sobre esto aquí.

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

Alternativamente, podría #tener en cuenta que esto actuará como un ancla y se desplazará hacia la parte superior de la página.

<form action="#">
Peros
fuente
¿Le gustaría entender por qué alguien ha rechazado esta respuesta?
Buts
Omitir el atributo de acción, ¿el formulario aún abierto a exploits se detalla en la primera página del enlace?
Richard Young
@RichardYoung Lo siento, no entiendo tu pregunta. Por favor, reformule.
Buts
1
Los hackers pueden usar la variable $ _SERVER ["PHP_SELF"]. Si se usa PHP_SELF en su página, un usuario puede ingresar una barra diagonal (/) y luego algunos comandos Cross Site Scripting (XSS) para ejecutar. Si omite el atributo de acción, ¿sigue siendo vulnerable a esto?
Richard Young
Sí es usted. El atributo de acción se puede volver a agregar en el lado del cliente y se le puede dar cualquier valor de elección. Sin embargo, el uso de la htmlspecialchars()función impide que las personas usen su script php en su contra.
Buts
4

Normalmente uso action = "", que es válido para XHTML y retiene los datos GET en la URL.

Juzgando
fuente
44
Rara vez, pero por ejemplo, en mi foro, tendría la URL: thread.php? Id = 12 & page = 6 y hay un formulario POST en la parte inferior de la página para agregar comentarios, y necesito los datos GET para que el PHP sabe a qué hilo agregar el comentario.
Juicio
20
GET es el método predeterminado para los formularios: no es algo malo ;-) w3.org/TR/html401/interact/forms.html#adef-method
NickFitz
55
Usar GET en formularios es algo malo. Si el usuario vuelve a cargar la página después de enviarla, puede haber consecuencias no deseadas. Sin embargo, si se utiliza una POST, el navegador advertirá sobre el reenvío de los mismos datos.
Will Sheppard
22
@ WillSheppard No estoy de acuerdo. No puedes hacer una declaración general como esa. Todo depende de lo que haga el formulario. Debe usar POST para cualquier cosa que realice una acción (por ejemplo, insertar una nueva publicación en un foro), pero OBTENER para todo lo demás (por ejemplo, un cuadro de búsqueda o usar formularios para la navegación). Después de una POST exitosa, el script debe redirigir el navegador para evitar que el usuario vuelva a enviar los datos.
Mike
3
PD: no todos los navegadores advierten al usuario sobre el reenvío de datos POST (por ejemplo, Opera)
Mike
4

Creo que es mejor indicar explícitamente dónde se publica el formulario. Si desea estar totalmente seguro, ingrese la misma URL en la que se encuentra el formulario en el atributo de acción si desea que se envíe nuevamente. Aunque los navegadores convencionales evalúan ""la misma página, no puede garantizar que los navegadores no convencionales lo hagan.

Y, por supuesto, la URL completa, incluidos los datos GET, como Juddling, señala.

Will Morgan
fuente
2

Solo usa

?

<form action="?" method="post" enctype="multipart/form-data" name="myForm" id="myForm">

No viola los estándares HTML5.

M_R_K
fuente
No voté en contra, pero su método eliminará todos los getparámetros. Un formulario en la siguiente URL se rompería example.com/update_user?user_id=1porque el formulario se enviará aexample.com/update_user?
vikki
1

Solía ​​hacer esto mucho cuando trabajaba con ASP clásico. Por lo general, lo usé cuando se necesitaba algún tipo de validación del lado del servidor para la entrada (antes de los días de AJAX). El principal inconveniente que veo es que no separa la lógica de programación de la presentación, a nivel de archivo.

busse
fuente
1
¿Por qué no? Creo que no está conectado. Puedo hacer que un formulario publique los datos en la misma página y cree esta página con la separación adecuada del controlador y la vista.
markus
1

Solía ​​no especificar el atributo de acción en absoluto. En realidad es cómo está diseñado mi marco, todas las páginas se envían exactamente a la misma dirección. Pero hoy descubrí el problema. A veces tomo prestado el valor del atributo de acción para hacer una llamada de fondo (supongo que algunas personas los llaman AJAX). Entonces descubrí que IE mantiene el valor del atributo de acción como vacío si no se especificó el atributo de acción. En mi opinión, es un poco extraño, ya que si no se especifica ningún atributo de acción, la contraparte de JavaScript debe estar al menos indefinida. De todos modos, mi punto es que antes de elegir la mejor práctica, necesita comprender más contexto, como si usará el atributo en JavaScript o no.

Singagirl
fuente