JavaFX WebView自定义协议下如何使用JavaScript Fetch API?
问题:JavaFX WebView自定义协议无法支持JavaScript Fetch/XMLHttpRequest请求
我在JavaFX WebView中尝试从Jar文件加载资源,基于自定义resource协议实现了URLStreamHandlerFactory及相关逻辑,目前除JavaScript的Fetch和XMLHttpRequest调用外,其余功能均正常。
自定义URLStreamHandlerFactory实现
public class ResourceURLStreamHandlerFactory implements URLStreamHandlerFactory { ResourceURLStreamHandlerFactory() { } @Override public URLStreamHandler createURLStreamHandler(String protocol) { if (protocol.equals("resource")) return new ResourceURLHandler(); System.out.println("Unknown "+protocol); return null; } public static class ResourceURLHandler extends URLStreamHandler { @Override protected URLConnection openConnection(URL url) throws IOException { return new ResourceURLConnection(url); } } }
ResourceURLConnection实现
public class ResourceURLConnection extends URLConnection { private byte[] data; public ResourceURLConnection(URL url) { super(url); } @Override public void connect() throws IOException { if (connected) return; loadURL(); connected = true; } @Override public String getHeaderField(String name) { if ("Content-Type".equalsIgnoreCase(name)) return getContentType(); else if ("Content-Length".equalsIgnoreCase(name)) return "" + getContentLength(); return null; } @Override public String getContentType() { String fileName = getURL().getFile(); int index = fileName.lastIndexOf('.'); if (index == -1) return "text/html"; String ext = fileName.substring(index+1); switch (ext) { case "htm": case "html": return "text/html"; case "js": return "text/javascript"; case "svg": return "image/svg+xml"; case "json": return "application/json"; case "png": return "image/png"; case "css": return "text/css"; } throw new RuntimeException("Unknown file type " + ext); } @Override public int getContentLength() { return data.length; } @Override public long getContentLengthLong() { return data.length; } @Override public boolean getDoInput() { return true; } @Override public InputStream getInputStream() throws IOException { connect(); return new ByteArrayInputStream(data); } private void loadURL() throws IOException { if (data != null) return; String path = getURL().toExternalForm(); path = path.startsWith("resource://") ? path.substring("resource://".length()) : path.substring("resource:".length()); URL resourceUrl = this.getClass().getClassLoader().getResource(HOME + path); if (resourceUrl != null) { try (InputStream is = resourceUrl.openStream()) { data = is.readAllBytes(); } } else { throw new IOException("Resource not found"); } } @Override public OutputStream getOutputStream() throws IOException { return new ByteArrayOutputStream(); } @Override public java.security.Permission getPermission() throws IOException { return null; // we need no permissions to access this URL } }
注册自定义协议处理器
static { URL.setURLStreamHandlerFactory(new ResourceURLStreamHandlerFactory()); }
加载网页资源
webEngine.load("resource:///hello.html");
JavaScript Fetch调用及错误
Fetch代码:
try { console.log("Start fetch " + path); const response = await fetch(path); console.log("Done fetch"); return; } catch (ex) { console.log("Fail " + ex + " " + path); }
收到的模糊错误:
TypeError: Load failed my.svg
疑问
目前Java端加载资源完全正常,但JavaScript的Fetch和XMLHttpRequest调用没有任何触发Java端资源加载逻辑的迹象,仅返回模糊错误。想知道:
- 是否有人成功实现过自定义协议支持JavaScript的网络请求?
- 有没有调试WebKit与Java交互的相关资源?
内容的提问来源于stack exchange,提问作者Karl Nelson
相关产品推荐
相关产品推荐

