JavaFX WebView / WebEngine缓存外部JavaScript

问题描述 投票:4回答:6

情况:我有一个简单的HTML页面,它有一个像这样的普通脚本标签

<script src="main.js"></script>

加载html后,我更新main.js,并重新加载(通过UI按钮)。

问题我没有采用新的JS,我必须关闭应用程序并再次打开它。

我做了什么尝试: - 不使用webEngine.reload(),但webEngine.load() - 每次重新加载时都会制作一个新的broswer。 - 使用新的broswer设置一个新阶段 - 设置所有节点缓存 - 在HTML代码之后

<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选项:-Dnetworkaddress.cache.ttl = 0。

问题是否有任何方法可以删除缓存或强制WebView重新加载所有资源,而不是每次更新时都将数字附加到JS文件名?

注意:我使用NetBeans 7.3和上一个Java(更新22)

java caching webview javafx browser-cache
6个回答
0
投票

当我使用用户编辑的css文件时,我遇到了类似的问题。 UI的目标是允许用户编辑从给定外部.html文件加载的外部.css文件,并在WebEngine中实时查看更改。

我也无法找到任何对缓存的引用来清除或强制WebEngine重新加载其所有资源的任何方法。但我确实想出了一个表现良好的解决方案。

我最终做的是将外部html文件的内容加载到内存中,并使用<style>内嵌css标记替换引用相关外部.css文件的<link>标记,其中包含.css的内容文件。然后我用了

WebEngine.loadContent(EditedHTML); 

传递新编辑的HTML。可以轻松更改此技术,以将外部JS文件加载到内联<Script>标记中。

这项技术对我来说非常有效,因为我加载和编辑的所有文件都是本地的。我将其内容加载到内存中并在应用程序启动时保存对它们的引用。如果您尝试将JS文件添加到从服务器http请求检索的webPage中,将此技术包含在您的应用程序中可能会更困难,但我认为这不可能。

具体实现将取决于您的应用程序的整体结构,但sudo代码将是这样的:

  1. 加载html文件的内容。
  2. 将内容解析为HTML文档。*
  3. 对于每个css <link>标记 加载相关的css文件的内容 将链接标记替换为<style>标记,其内容是加载的css文件的内容
  4. 调用WebEngine.loadContent(editedHTML)

*为了将内容解析为HTML文档,可以使用许多有用且易于使用的库。 This SO问题是寻找一些最常用的问题的好地方。我使用jSoup并发现它非常简单,功能强大且有效,并且建议您至少先查看/试用它,然后选择另外一个。

这可能需要对您的应用程序进行一些重新构建,但这种技术是我提出的最佳解决方案。如果您有任何问题/疑虑,请告诉我,我将尝试根据我对此技术的经验回答/解决这些问题。


0
投票

我是如何解决这个问题的:

  • 将包含HTML文件和所有JS文件的目标目录复制到随机生成的文件夹中。
  • on每次重新加载都会生成一个新文件夹,复制内容,删除旧文件夹,从新文件夹加载。

“mcdonasm”的答案是我尝试过的事情之一,如果在“main.js”中只有JavaScript,它可以工作,但如果它引用其他JS文件(就我的情况而言),其他的将被缓存。


0
投票

我有类似的要求,但想要一个固定的目录位置。这对我有用:

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();
        }
    }
});

基本上强制重新加载一次,它也会刷新外部数据。


0
投票

如下所述:http://docs.oracle.com/javafx/8/webview/overview.htm

使用WebView组件时,您应该记住它具有默认的内存缓存。这意味着一旦关闭包含WebView组件的应用程序,任何缓存的内容都将丢失。

因此,如果我们在Webview中“动态”更改脚本或css文件,则不会重新加载/刷新此文件:-( 我找到了另一种解决方法,与@Rany中找到的不同(似乎更简单)。我会解释它,希望它可以帮助别人......

只需在调用脚本或样式表的末尾添加一个自定义参数。 例如,改为写这个:

<script type="text/javascript" src="javascript.js"></script>

写这个:

<script type="text/javascript" src="javascript.js?c=r_963"></script>

其中“r_963”是一个“r_”字符串,后跟一个随机的0-999 int数字。每当我们需要刷新时,最终的数字必须改变它的值。 样式表也一样。 这个对我有用 :-)


0
投票

几个小时后,我发现了一个非常方便的方式,我想分享:

webEngine.setJavaScriptEnabled(true);
webEngine.executeScript("location.reload(true);");

显然,JavaFX WebView的JavaScript引擎完全支持JavaScript方法location.reload(true)。 “true”强制从服务器(或本地文件系统)重新加载资源。我和它一起尝试过。如果我更改文件的内容并在WebEngine中执行上面的js代码,图像将被替换,并且js-code将在bar.js中更改执行。

遗憾的是,没有Java方法可以方便地访问此功能。

我承认,它并没有真正清除缓存,但它会重新加载源,这对于大多数情况应该足够了。

在JRE 1.8.0_91中测试过


0
投票

我有类似的问题,但有样式表。我正在开发一个Web创作工具,并希望在不重新启动应用程序的情况下反映显示的HTML文件中的样式表更改。

我发现唯一有效的方法是创建一个新的WebView对象(永远不会显示)并在其中显式加载样式表。完成后,刷新任何引用该样式表的html文件将自动反映更改。

/** Forces an update to the internally-cached stylesheet.
 * @param file The CSS file.
 */
private void updateInternalCache(File file) {
    WebView cssLoader = new WebView();
    String fileLocation = file.toURI().toString();
    cssLoader.getEngine().load(fileLocation);
}
© www.soinside.com 2019 - 2024. All rights reserved.