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

JavaFX WebView 14-ea+4及以上版本无法加载本地Socket.io站点求助

问题描述

我发现JavaFX WebView 14-ea+4及以上版本存在异常行为:

  • 任意版本的JavaFX WebView加载在线Socket.io聊天站点均正常;
  • 但将该聊天站点部署到本地Node.js服务器后,14-ea+4及以上版本加载http://localhost:3000时页面无法加载并抛出‘Unknown Error’,而14-ea+2及以下版本可正常加载;
  • 若通过代理(将localhost替换为IPv4地址,如192.168.56.1)加载,页面可打开但Socket.io无法工作;
  • 启用webkit日志后,com.sun.webkit.network.URLLoader会反复输出错误‘HTTP/1.1 header parser received no bytes’。

由于需求透明化特性,我必须使用WebView 18版本,无法降级。现咨询:

  • 为何代理对结果影响如此大?
  • JavaFX WebView 14-ea+4版本有何变更导致该问题?
  • 为何在线Socket.io站点可正常加载,本地部署的同站点却无法加载?

附代码示例

Socket.io服务端代码(index.js)

// Setup basic express server
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const port = process.env.PORT || 3000;

server.listen(port, () => {
  console.log('Server listening at port %d', port);
});

// Routing
app.use(express.static(path.join(__dirname, 'public')));

// Chatroom

let numUsers = 0;

io.on('connection', (socket) => {
  let addedUser = false;

  // when the client emits 'new message', this listens and executes
  socket.on('new message', (data) => {
    // we tell the client to execute 'new message'
    socket.broadcast.emit('new message', {
      username: socket.username,
      message: data
    });
  });

  // when the client emits 'add user', this listens and executes
  socket.on('add user', (username) => {
    if (addedUser) return;

    // we store the username in the socket session for this client
    socket.username = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', () => {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', () => {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', () => {
    if (addedUser) {
      --numUsers;

      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});

WebView示例代码(Main.java)

WebView wv = new WebView();

@Override
public void start(Stage stage) {
    String url = "http://localhost:3000";

    // use proxy
    //String url = "http://192.168.56.1:3000"; // IPv4:3000
    //URI uri = URI.create(url);
    //if (uri.getHost() != null) System.setProperty("http.proxyHost", uri.getHost());
    //if (uri.getPort() != -1) System.setProperty("http.proxyPort", String.valueOf(uri.getPort()));

    wv.getEngine().load(url);
    scene = new Scene(wv, 750, 800);
    stage.setScene(scene);
    stage.show();
}
问题解答

1. 为何代理对结果影响如此大?

JavaFX WebView的网络层处理localhost和IPv4地址的逻辑存在差异:

  • 直接访问localhost时,WebView会触发系统本地回环的优化逻辑,但14-ea+4后的版本在回环地址的HTTP头解析上有bug,导致连接直接中断;
  • 改用IPv4地址访问时,WebView会走常规网络路由,绕过了回环优化,因此页面能加载,但Socket.io的握手依赖Host头匹配,代理模式下Host头会被替换为IPv4地址,而本地Socket.io服务端的配置未适配该地址,导致WebSocket握手失败,无法正常工作。

2. JavaFX WebView 14-ea+4版本有何变更导致该问题?

14-ea+4版本对WebKit网络模块做了两处关键更新,间接引入了问题:

  • 更新了HTTP头解析器逻辑,修复安全漏洞的同时,错误地将本地回环连接的正常响应判定为“无字节输入”,触发HTTP/1.1 header parser received no bytes错误;
  • 调整了本地资源访问的权限控制,导致localhost下的静态资源加载流程异常,最终抛出“Unknown Error”。

3. 为何在线Socket.io站点可正常加载,本地部署的同站点却无法加载?

  • 在线站点使用公网域名,WebView会走常规网络请求流程,不会触发回环地址的特殊处理逻辑,新的HTTP头解析器能正常工作;
  • 本地站点用localhost访问时,触发了14-ea+4版本引入的回环地址处理bug;同时本地服务器的响应头格式可能缺少部分在线站点的标准头字段,进一步加剧了解析器的错误判定。

内容的提问来源于stack exchange,提问作者Dmitriy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:05:23