JavaFX WebView/WebEngine Cache JavaScript externo
caching browser-cache (4)
Situación : tengo una página HTML simple que tiene una etiqueta de script normal como esta
<script src="main.js"></script>
Después de cargar el html, actualizo main.js y realizo una recarga (a través del botón UI).
El problema Mi nueva JS no se toma, debo cerrar la aplicación y abrirla nuevamente.
Lo que sí intenté: no usar webEngine.reload (), sino webEngine.load (): hacer un nuevo broswer cada vez que se produce una recarga. -hacer una nueva etapa con un nuevo broswer-configurar todos los nodos en caché -en código HTML siguiente
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
-InetAddressCachePolicy:
InetAddressCachePolicy.setNegativeIfNotSet(InetAddressCachePolicy.NEVER);
-VM Opciones: -Dnetworkaddress.cache.ttl = 0.
La pregunta ¿Hay alguna manera de eliminar la memoria caché o aplicar WebView para volver a cargar todos los recursos además de agregar un número al nombre del archivo JS cada vez que lo actualizo?
Nota: uso NetBeans 7.3 con la última versión de Java (actualización 22)
Cómo trabajé en eso:
- Copie el directorio de destino que contiene el archivo HTML y todos los archivos JS en una carpeta generada al azar.
- en Cada recarga, genere una nueva carpeta, copie los contenidos, elimine la carpeta anterior, cargue desde la nueva carpeta.
La respuesta de "mcdonasm" fue una de las cosas que probé, funcionaría si en "main.js" solo está JavaScript, pero si hace referencia a otros archivos JS (como mi caso), los demás serán almacenados en caché.
Tenía un requisito similar, pero quería una ubicación de directorio fija. Esto funcionó para mí:
first = true;
final WebView view = new WebView();
view.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override
public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State t1) {
System.out.println(t1);
if(t1.equals(State.SUCCEEDED) && first) {
first = false;
view.getEngine().reload();
}
}
});
Básicamente fuerce una recarga una vez y también actualizará los datos externos.
como se describe aquí: http://docs.oracle.com/javafx/8/webview/overview.htm
Al trabajar con el componente WebView, debe recordar que tiene el caché en memoria predeterminado. Significa que cualquier contenido en caché se pierde una vez que se cierra la aplicación que contiene el componente WebView.
Entonces, si cambiamos "sobre la marcha" un script o un archivo css dentro de un Webview, este archivo no se volverá a cargar / actualizar :-(
He encontrado otra solución, diferente (y parece más simple) de la que se encuentra en @Rany. Lo explicaré con la esperanza de que pueda ayudar a alguien ...
Simplemente agregue al final de la llamada al script o hoja de estilo un parámetro personalizado .
Por ejemplo, en lugar de escribir esto:
<script type="text/javascript" src="javascript.js"></script>
escribe esto:
<script type="text/javascript" src="javascript.js?c=r_963"></script>
donde "r_963" es una cadena "r_" seguida de un número aleatorio 0-999 int. El número final debe cambiar su valor cada vez que necesitemos una actualización.
Lo mismo para stylesheet.
Esto funciona para mi :-)
Tuve un problema similar cuando estaba trabajando con archivos css editados por el usuario. El objetivo de la interfaz de usuario era permitir al usuario editar los archivos .css externos cargados desde un archivo .html externo determinado y ver los cambios en tiempo real en WebEngine.
Tampoco pude encontrar ninguna referencia a un caché para borrar o forzar a WebEngine a volver a cargar todos sus recursos. Pero se me ocurrió lo que resultó ser una solución de buen rendimiento.
Lo que terminé haciendo fue cargar el contenido del archivo html externo en la memoria y reemplazar las etiquetas <link> que hacen referencia a los archivos .css externos asociados, con las etiquetas css en línea <style> que contienen los contenidos del archivo .css archivos. Entonces utilicé
WebEngine.loadContent(EditedHTML);
pasando el HTML recientemente editado. Esta técnica podría modificarse fácilmente para cargar archivos JS externos en etiquetas <Script> en línea.
Esta técnica funcionó muy bien para mí porque todos los archivos que estoy cargando y editando son locales. Cargué sus contenidos en la memoria y guardo referencias a ellos en el inicio de la aplicación. Si está intentando agregar archivos JS a una página web recuperada a partir de una solicitud HTTP del servidor, puede ser una pero más difícil de incluir esta técnica en su aplicación, aunque no creo que sea imposible.
La implementación específica dependería de la estructura general de su aplicación, pero el código de sudo sería algo como esto:
- Cargue los contenidos del archivo html.
- Analizar contenido en documento HTML. *
- Para cada etiqueta css <link>
- Carga los contenidos del archivo css asociado
- Reemplazar la etiqueta de enlace con la etiqueta <style>, cuyos contenidos son los contenidos del archivo css cargado
- Llamar a WebEngine.loadContent (editedHTML)
* Para analizar el contenido en un documento HTML, hay muchas bibliotecas útiles y fáciles de usar que se pueden utilizar. Esta pregunta SO es un buen lugar para buscar algunos de los más utilizados. Utilizo jSoup y considero que es muy simple, potente y eficaz y le recomendaría que al menos lo busque o lo pruebe antes de optar por uno diferente.
Esto puede requerir alguna reestructuración de su aplicación, pero esta técnica fue de lejos la mejor solución que se me ocurrió. Avíseme si tiene alguna pregunta o inquietud e intentaré responder / abordarla desde mi experiencia con esta técnica.