基于GJS与WebKit2获取响应头及脚本通信技术问询
解决GJS+WebKit2的两个核心需求:获取响应头与JS-GJS消息交互
一、修复Response.get_uri为空的问题,正确获取HTTP响应头
你之前的代码里自己实例化了WebKit.URIResponse(),这是一个空对象,和实际请求的响应完全无关。要拿到真实的响应数据,得监听WebView的resource-load-finished信号,从信号参数里提取请求对应的资源对象:
- 监听
resource-load-finished信号,该信号会返回请求对应的WebKit.Resource实例 - 调用
resource.get_response()获取真实的URIResponse对象 - 通过
URIResponse.get_uri()拿到请求URL,get_headers()获取完整HTTP响应头
二、实现JS脚本与GJS的消息交互,传递页面HTML
要让注入的JS和GJS双向通信,需要用到UserContentManager的消息机制:
- 给
UserContentManager注册一个自定义消息通道(比如命名为html-message) - 监听
script-message-received信号,接收JS发来的消息内容 - 在注入的JS脚本里,通过
window.webkit.messageHandlers[通道名].postMessage()发送页面HTML
修改后的完整代码
const Gtk = imports.gi.Gtk; const WebKit = imports.gi.WebKit2; Gtk.init(null); // 创建UserContentManager并注册消息通道 const contentManager = new WebKit.UserContentManager(); contentManager.register_script_message_handler("html-message", null); // 创建关联UserContentManager的WebView const view = WebKit.WebView.new_with_user_content_manager(contentManager); // 初始化窗口 const win = new Gtk.Window(); win.add(view); win.set_title("test"); win.set_icon_from_file("/games/aptdaemon-resolve.png"); win.connect('destroy', () => { Gtk.main_quit(); }); win.set_size_request(640, 480); // 监听资源加载完成事件,获取响应头和URL view.connect("resource-load-finished", (_, resource) => { const response = resource.get_response(); if (response) { log(`请求URL: ${response.get_uri()}`); // 遍历打印响应头 const headers = response.get_headers(); log("响应头信息:"); headers.foreach((name, value) => { log(` ${name}: ${value}`); }); } }); // 监听JS发来的消息,接收HTML内容 contentManager.connect("script-message-received", (_, message) => { const htmlContent = message.get_js_value().to_string(); log("\n收到页面HTML内容:"); log(htmlContent); }); // 注入页面加载完成后发送HTML的脚本 const injectScript = new WebKit.UserScript( `window.addEventListener('load', () => { window.webkit.messageHandlers['html-message'].postMessage(document.body.innerHTML); });`, WebKit.UserContentInjectedFrames.TOP_FRAME, WebKit.UserScriptInjectionTime.END, null, null ); contentManager.add_script(injectScript); // 加载目标页面 view.load_uri('https://www.gnome.org'); win.show_all(); Gtk.main();
关键改动说明
- 移除了无用的空
URIResponse实例,改为从真实请求资源中提取响应数据 - 新增消息通道注册与监听逻辑,实现JS和GJS的双向通信
- 注入脚本改为在页面完全加载后发送HTML,确保获取到完整内容
- 通过
resource.get_response()拿到的响应对象,可正常调用get_uri()和get_headers()获取有效数据
内容的提问来源于stack exchange,提问作者Schmaehgrunza
相关产品推荐
相关产品推荐

