我的web应用程序提供下载。 Javascript创建点击url(取决于用户输入),浏览器应该打开它,这样页面不会被重新加载。使用JavaFX下载WebView
对于这一点,我想我必须选择:
// Alt1:
window.open(pathToFile);
// Alt2:
var downloadFrame = document.getElementById('downloads');
if (downloadFrame === null) {
downloadFrame = document.createElement('iframe');
downloadFrame.id = 'downloads';
downloadFrame.style.display = 'none';
document.body.appendChild(downloadFrame);
}
downloadFrame.src = pathToFile;
下的Firefox这两部作品。打开新窗口方法时出现的问题:如果在服务器上创建文件需要更多时间,则新的空标签将迟到。 iframe问题:如果服务器出现错误,则不会给出反馈。
我认为在Firefox上iframe是更好的解决方案。但是,Web应用程序也必须使用JavaFX WebView运行。 JavaFX没有下载功能,我必须编写它。一种可能的方式是听上的位置属性:
final WebView webView = new WebView();
webView.getEngine().locationProperty().addListener(new ChangeListener<String>() {
@Override public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) {
if (newLoc.cotains("/download")) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Save " + newLoc);
File saveFile = chooser.showSaveDialog(webView.getEngine().getScene().getWindow());
if (saveFile != null) {
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
is = new BufferedInputStream(new URL(newLoc).openStream());
os = new BufferedOutputStream(new FileOutputStream(saveFile));
while ((readBytes = is.read()) != -1) {
os.write(b);
}
} finally {
try { if (is != null) is.close(); } catch (IOException e) {}
try { if (os != null) os.close(); } catch (IOException e) {}
}
}
}
}
}
存在一些问题:
- 下载开始依赖于URL的一部分,因为JafaFX支持HTTP头没有访问(这是可以忍受的)
- 如果用户使用同一个url开始下载两次,只有第一次下载工作(如果url是新的,只会触发更改事件)。我可以创建独特的网址(最后是#1,#2等)。但这很丑陋。
- 只有“window.open(pathToFile);”方法起作用。加载iframe不会触发网站的更改位置事件。这是可以预期的,但我没有找到合适的听众。
有人可以帮我解决2.或3.?
谢谢! PS:对不起,我的英语不好。
编辑: 对于2.我找到了一种方法。我不知道它是否是一个好的,如果它是高性能的,如果新的webview被删除或下载后在缓存中,... 并且用户没有得到反馈,当出现问题时提高:
webView.getEngine().setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
@Override public WebEngine call(PopupFeatures config) {
final WebView downloader = new WebView();
downloader.getEngine().locationProperty().addListener(/* The Listener from above */);
return downloader.getEngine();
}
}