You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:41:19