Se proporciona un script simple para evitar múltiples clics en un botón de envío como en el siguiente ejemplo (reducido): Después del primer clic, no se puede hacer clic en el botón hasta que se cargue el siguiente formulario con una demora deliberada de 2 segundos.
<?php sleep(2); ?> <html> <body> <script type="text/javascript"> var done = false; function once() { if (done) { return false; } done = true; return true; } </script> <form method="POST" onsubmit="return once();"> <input type="submit" value="ok"> </form> </body> </html>Esto funciona bien, pero desencadenó una auditoría de seguridad. Content-Security-Policy será obligatorio, por lo que todos los controladores de eventos deben asignarse mediante secuencias de comandos mediante un nonce.
Esto también funciona bien, excepto por este script de bloqueo. La nueva versión se ve así:
<?php sleep(2); header("Content-Security-Policy: script-src 'self' 'nonce-test'", true); ?> <html> <body> <script type="text/javascript" nonce="test"> var done = false; function once() { if (done) { return false; } done = true; return true; } </script> <form id="1" method="POST"> <input type="submit" value="ok"> </form> <script type="text/javascript" nonce="test"> document.getElementById("1").addEventListener('submit', function(e) { return once(); }); </script> </body> </html> La funcionalidad básica está ahí; se asigna el controlador de eventos, y con un punto de interrupción en done = true puedo comprobar que se llama cuando hago clic en el botón. Pero cada clic repetido en el botón crea una nueva solicitud que es exactamente lo que no debería suceder.
¿Por qué estos dos scripts se comportan de manera diferente?