La aplicación web Apps script funciona en <iframe> . Parece que Chrome ya no es compatible con alert() , confirm() , Promociona estas funciones en la aplicación web.
¿Alguna solución a esto?
Intenté reemplazar alert() con window.alert() , pero aún no funciona.
exec:1 Un subtrama de origen diferente intentó crear un diálogo de JavaScript. Esto ya no está permitido y fue bloqueado. Consulte https://www.chromestatus.com/feature/5148698084376576 para obtener más detalles.
Hasta ahora, la única 'solución' para esto es agregar lo siguiente al acceso directo de su navegador Chrome/Edge:
--disable-features="SuppressDifferentOriginSubframeJSDialogs"O degrada tu navegador. Obviamente ninguno de estos es ideal. Google se esfuerza mucho por salvarnos de nosotros mismos aquí.
Considere la posibilidad de presentar una solicitud de función utilizando esta plantilla de seguimiento de problemas.
Solicitaría que se haga una excepción para las aplicaciones web de Apps Script, o que se agreguen métodos integrados para alertar yconfirmar , de forma similar a los cuadros de diálogo de alerta y solicitud existentes, que actualmente funcionan en los editores de Google.
Por cierto, este comportamiento se ha informado en Issue Tracker (como un error):
Consideraría protagonizarlo para hacer un seguimiento de él.
Mientras tanto, como dijeron otros, considere degradar o cambiar el navegador, o ejecutarlo con el siguiente indicador de línea de comando:
--disable-features="SuppressDifferentOriginSubframeJSDialogs"
Esta es una decisión absurda y subjetiva de Google de eliminar alert(), confirm() y prompt() para iframes de origen cruzado. Y lo llamaron " característica ". Y la justificación es muy pobre: vea "motivación" a continuación. ¡Una razón muy débil para eliminar una característica tan importante! ¡La comunidad y los desarrolladores deberían protestar!
https://www.chromestatus.com/feature/5148698084376576
Característica : eliminar alerta (), confirmar () y solicitar iframes de origen cruzado
Chrome permite que los iframes activen cuadros de diálogo de Javascript, muestra "dice..." cuando el iframe tiene el mismo origen que el marco superior y "Una página incrustada en esta página dice..." cuando el iframe tiene un origen cruzado. La UX actual es confusa y anteriormente ha dado lugar a falsificaciones en las que los sitios fingen que el mensaje proviene de Chrome o de un sitio web diferente. Eliminar la compatibilidad con la capacidad de iframes de origen cruzado para activar la interfaz de usuario evitará este tipo de suplantación de identidad y desbloqueará más simplificaciones de la interfaz de usuario.
Motivación
La interfaz de usuario actual para los cuadros de diálogo JS (en general, no solo para el caso de subtramas de origen cruzado) es confusa, porque el mensaje se parece a la propia interfaz de usuario del navegador. Esto ha llevado a falsificaciones (particularmente con window.prompt) donde los sitios fingen que un mensaje en particular proviene de Chrome (por ejemplo, 1,2,3). Chrome mitiga estas falsificaciones anteponiendo el mensaje con "dice...". Sin embargo, cuando estas alertas provienen de un iframe de origen cruzado, la interfaz de usuario es aún más confusa porque Chrome intenta explicar que el cuadro de diálogo no proviene del navegador o de la página de nivel superior. Dado el bajo uso de diálogos JS de iframe de origen cruzado, el hecho de que cuando se usan diálogos JS generalmente no son necesarios para la funcionalidad principal del sitio y la dificultad para explicar de manera confiable de dónde proviene el diálogo, proponemos eliminar los diálogos JS para iframes de origen cruzado. Esto también desbloqueará nuestra capacidad de simplificar aún más el cuadro de diálogo eliminando la indicación del nombre de host y haciendo que el cuadro de diálogo sea más obvio como parte de la página (y no del navegador) al moverlo al centro del área de contenido. Estos cambios se bloquean al eliminar la compatibilidad entre orígenes para los diálogos de JS, ya que, de lo contrario, estos submarcos podrían fingir que su diálogo proviene de la página principal.
Envíe un mensaje a través de Window.postMessage() desde iframe al padre y muestre el diálogo a través de la página principal. Es un truco muy elegante y una vergüenza en Google porque antes de la versión 92 de Chrome, el cliente vio un cuadro de diálogo de alerta, por ejemplo An embedded page iframe.com" says: ... (lo cual era correcto: el cliente ve el dominio real que invocó la alerta) pero ahora con el cliente de solución postMessage verá una mentira, por ejemplo The page example.com" says: ... pero la alerta no fue invocada por ejemplo.com. La estúpida decisión de Google hizo que lograran el efecto contrario: el cliente estará mucho más confundido ahora. La decisión de Google fue precipitada y no pensaron en las consecuencias. En el caso de prompt() y confirm(), es un poco complicado a través de Window.postMessage() porque necesitamos enviar el resultado desde arriba al iframe.
¿Qué hará Google a continuación? ¿Deshabilitar Window.postMessage()? Deja Vu. Estamos de vuelta en la era de Internet Explorer... los desarrolladores pierden el tiempo haciendo estúpidos trucos.
https://dominio-a.netlify.app/parent.html
Con el siguiente código, puede usar alertas nativas reemplazadas (), confirmar () y solicitar () en iframe de origen cruzado con un cambio de código mínimo. No hay cambios para el uso de alerta(). En el caso de confirmar () y solicitar () simplemente agregue la palabra clave "esperar" antes o siéntase libre de usar la devolución de llamada en caso de que no pueda cambiar fácilmente sus funciones de sincronización a funciones asíncronas. Vea todos los ejemplos de uso en iframe.html a continuación.
Todo lo malo viene con algo bueno: ahora obtuve con esta solución la ventaja de que el dominio iframe no se revela (el dominio de la barra de direcciones ahora se usa en los cuadros de diálogo).
https://ejemplo-a.com/parent.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Parent (domain A)</title> <script type="text/javascript" src="dialogs.js"></script> </head> <body> <h1>Parent (domain A)</h1> <iframe src="https://example-b.com/iframe.html"> </body> </html>https://ejemplo-b.com/iframe.html
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Iframe (domain B)</title> <script type="text/javascript" src="dialogs.js"></script> </head> <body> <h1>Iframe (domain B)</h1> <script type="text/javascript"> alert('alert() forwarded from iframe.html'); confirm('confirm() forwarded from iframe.html via callback', (result) => { console.log('confirm() result via callback: ', result); }); prompt('prompt() forwarded from iframe.html via callback', null, (result) => { console.log('prompt() result via callback: ', result); }); (async () => { var result1 = await confirm('confirm() forwarded from iframe.html via promise'); console.log('confirm() result via promise: ', result1); var result2 = await prompt('prompt() forwarded from iframe.html via promise'); console.log('prompt() result via promise: ', result2); })(); </script> </body> </html>diálogos.js
(function() { var id = 1, store = {}, isIframe = (window === window.parent || window.opener) ? false : true; // Send message var sendMessage = function(windowToSend, data) { windowToSend.postMessage(JSON.stringify(data), '*'); }; // Helper for overridden confirm() and prompt() var processInteractiveDialog = function(data, callback) { sendMessage(parent, data); if (callback) store[data.id] = callback; else return new Promise(resolve => { store[data.id] = resolve; }) }; // Override native dialog functions if (isIframe) { // alert() window.alert = function(message) { var data = { event : 'dialog', type : 'alert', message : message }; sendMessage(parent, data); }; // confirm() window.confirm = function(message, callback) { var data = { event : 'dialog', type : 'confirm', id : id++, message : message }; return processInteractiveDialog(data, callback); }; // prompt() window.prompt = function(message, value, callback) { var data = { event : 'dialog', type : 'prompt', id : id++, message : message, value : value || '' }; return processInteractiveDialog(data, callback); }; } // Listen to messages window.addEventListener('message', function(event) { try { var data = JSON.parse(event.data); } catch (error) { return; } if (!data || typeof data != 'object') return; if (data.event != 'dialog' || !data.type) return; // Initial message from iframe to parent if (!isIframe) { // alert() if (data.type == 'alert') alert(data.message) // confirm() else if (data.type == 'confirm') { var data = { event : 'dialog', type : 'confirm', id : data.id, result : confirm(data.message) }; sendMessage(event.source, data); } // prompt() else if (data.type == 'prompt') { var data = { event : 'dialog', type : 'prompt', id : data.id, result : prompt(data.message, data.value) }; sendMessage(event.source, data); } } // Response message from parent to iframe else { // confirm() if (data.type == 'confirm') { store[data.id](data.result); delete store[data.id]; } // prompt() else if (data.type == 'prompt') { store[data.id](data.result); delete store[data.id]; } } }, false); })();