2010-08-28 10 views
10

En una página, algo así como jsFiddle, que ejecuta el Javascript invocado por el usuario, ¿hay alguna manera de detener/interrumpir los scripts "problemáticos" que se ejecutan en un iframe?Al ejecutar el Javascript de usuario invocado, ¿hay alguna manera de detectar y detener los scripts "problemáticos"?

La clase principal de scripts de problemas serían bucles infinitos, creo. Los navegadores manejan bastante bien varias alertas, pero una secuencia de comandos como, ​for (var i = 0; ++i; i < 100) { /* do stuff */ }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ será para siempre.

¿Cómo puedo detectar y no ejecutar, o ejecutar y detener, digamos después de 10 segundos de ejecución, un script?

Eliminar el iframe está bien, pero solo quiero eliminarlo si el script se sigue ejecutando después de 10 segundos, pero no quiero eliminarlo si el script ha dejado de ejecutarse.


Así es como me imagino que la página va a funcionar. Si usted tiene una mejor solución, que me haga saber ...

La página de entrada contiene un textarea y un espacio en blanco iframe. El usuario ingresa su script en el textarea, y cuando está listo, hace clic en run. Luego (backstage) se crea una página separada que contiene el script del usuario en forma ejecutable en una página HTML. El src del iframe se establece en la página con el código ejecutable. Todo esto sucede dinámicamente sin una actualización de página.

+0

Borraste la otra pregunta antes de que tuviera oportunidad de responder, pero recuerda que ejecutar 'eval' significa que el código que tu usuario ingresa puede interactuar con los códigos que escribas, lo que significa que puede modificar variables, ejecutar funciones, etc. etc. Esta es la razón por la que desea que los sitios de la solución 'iframe' como jsfiddle usen para aislar el código. –

+0

@Yi Jiang, ¿Quizás pueda eliminar el 'iframe' después de, digamos, cinco segundos, para finalizar el script? – strager

+0

@Yi Jiang - Gracias por la sugerencia. ¿De modo que de alguna forma el src del iframe es la evaluación del script de usuario? –

Respuesta

2

No he usado este script jsandbox, pero parece tener lo que desea.

+0

Este o un enfoque similar debería funcionar porque usa trabajadores web HTML5, que se ejecutan en paralelo a la página principal. Como dijo SimpleCoder, muchos navegadores ejecutan un único hilo para todo el código JavaScript, por lo que JavaScript en la página no se estaría ejecutando si el JavaScript del iframe se ejecuta en un ciclo cerrado. – Annie

+0

Voy a ir con esta respuesta. Gracias por la sugerencia. Parece un camino prometedor para bajar. No tuve tiempo de probarlo todavía, pero parece que es la solución más prometedora. –

0

Creo que esto dependería en gran medida de la secuencia de comandos y cómo los navegadores manejan las secuencias de comandos en los marcos flotantes.

Digamos que hay un tiempo (verdadero) en el iframe.

El navegador puede bloquear o bloquear la pestaña (como lo hace Chrome), o puede bloquear el iframe. Si se bloquea o bloquea la pestaña, no hay nada que pueda hacer con JS para evitarlo, aparte de intentar un análisis estático en el script para encontrar declaraciones posiblemente problemáticas (Análisis estático para encontrar scripts problemáticos como que nunca sería infalible)

Suponiendo que el navegador solo bloquea el iframe o hace algo más al tiempo que permite que los scripts en la página principal hagan cosas, la eliminación del iframe después de un cierto período de tiempo es una opción.

El navegador también puede mostrar la ventana emergente "Script are slow". En este caso, lo más probable es que cierre por completo todos los scripts en la pestaña completa o solo en el iframe. Si solo fuera el iframe, los otros scripts en la pestaña aún podrían limpiar después del período de tiempo predefinido.

Otra alternativa sería evaluar previamente la secuencia de comandos en un tiempo de ejecución independiente donde usted mismo puede detectar cosas así. Podría ejecutar el script en, por ejemplo, Rhino, y determinar si lleva demasiado tiempo procesarlo, o algo similar.

1

Si un script se congela en una página, otros scripts no continuarán ejecutándose. Por lo tanto, no hay forma de detectar si otro script ha dejado de ejecutarse, sin usar un plugin personalizado o algo así. Los navegadores no usan subprocesos múltiples de esa manera.

+0

¿qué hay de usar las declaraciones try-catch? –

+3

try-catch puede detectar errores, pero no harán nada para detener bucles infinitos. –

+0

HTML 5 admite JavaScript Web Workers, que funcionan en hilos separados. – meiamsome

1

Puede establecer un tiempo de espera en la ventana principal que detiene/elimina la secuencia de comandos después de 10 segundos.Entonces solo tiene que borrar el tiempo de espera cuando el script haya terminado (solo agregue una línea como esta al script iframe: window.frames[0].clearTimeout(window.frames[0].timeoutName) - No sé si funciona, pero debería)

+1

Funcionaría si el script en el iframe fuera while (1); ¿por ejemplo? Siempre pensé que setTimeout tenía que esperar la primera oportunidad (sin otros scripts en ejecución) después de su tiempo de espera. Entonces, si el script nunca le dio la oportunidad a setTimeout de ejecutarse, el navegador se colgaría. Sin embargo, con el iframe no estoy seguro. – Bishnu

0

No sé si esto funcionaría exactamente, es posible que pueda hacer algo como esto para trabajar con un poco de retoques. Supongo que está tomando JavaScript en el texto y luego lo evalúa, ¿verdad? Puede analizar o incluso simplemente usar regex para reemplazar todas las llamadas a la declaración de función, durante ... entrada y salida con la llamada de función y luego una lógica que llama al código y determina si se ha estado ejecutando durante 10 segundos. Si lo tiene, volverá; o romper; o algo. El código probablemente se enloquecería después y probablemente comenzara a arrojar errores, pero al menos el script se detendría.

+0

No creo que 'eval()' el código. Crearía un archivo que contiene una versión ejecutable del código (w PHP a través de una llamada AJAX), y luego establecería el 'src' del' iframe' en ese archivo. –

+0

Lo anterior aún podría hacerse en el lado del servidor – Bishnu

Cuestiones relacionadas