我正在开发一个项目,其中使用 PySide6 的 QWebEngineView 来显示需要来自 Neo4j 数据库的数据的 D3.js 图形可视化。 HTML 页面使用 JavaScript 的 fetch API 向 Neo4j HTTP 端点发送请求,并使用 D3.js 可视化返回的数据。
当我在标准 Web 浏览器中运行 HTML 页面时,一切都按预期工作:从 Neo4j 数据库中获取数据,并且图形正确呈现。但是,当我尝试在 PySide6 QWebEngineView 中加载相同的 HTML 页面时,获取请求失败并出现以下 JavaScript 控制台错误:
JS Console(JavaScriptConsoleMessageLevel.ErrorMessageLevel): Error fetching data: TypeError: Failed to fetch
这是执行获取操作的 HTML 代码的相关部分:
<script>
async function fetchGraphData() {
const url = 'http://localhost:7474/db/neo4j/tx/commit'; // Neo4j HTTP endpoint
const username = 'neo4j';
const password = 'test';
try {
const response = await fetch(url, {
method: 'POST',
mode: 'cors',
headers: {
'Authorization': 'Basic ' + btoa(username + ':' + password),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"statements": [{
"statement": "MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 25"
}]
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log(data);
// Further processing...
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchGraphData();
</script>
这是简化的 PySide6 设置,我将 HTML 加载到 QWebEngineView 中:
from PySide6.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
from PySide6.QtCore import QUrl
import os
class MyGraphView(QWebEngineView):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
settings = self.settings()
settings.setAttribute(QWebEngineSettings.WebAttribute.JavascriptEnabled, True)
settings.setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
settings.setAttribute(QWebEngineSettings.WebAttribute.AllowRunningInsecureContent, True)
self.load(QUrl.fromLocalFile("/path/to/my/html/file.html"))
if __name__ == '__main__':
# App initialization and execution logic
此外,为了进一步调试问题,我尝试使用以下环境变量启用 QWebEngine 的远程调试功能:
os.environ['QTWEBENGINE_REMOTE_DEBUGGING'] = "0.0.0.0:9222"
但是,当我尝试连接调试界面时,我遇到了另一个WebSocket连接被拒绝的问题:
Rejected an incoming WebSocket connection from the http://localhost:9222 origin. Use the command line flag --remote-allow-origins=http://localhost:9222 to allow connections from this origin or --remote-allow-origins=* to allow all origins.
为了解决此问题,我尝试附加命令行标志以禁用网络安全并允许远程来源,如下所示:
if __name__ == "__main__":
# Application setup
sys.argv.append("--disable-web-security")
sys.argv.append("--remote-allow-origins=http://localhost:9222")
# Additional setup and application execution logic
尽管做出了这些努力,问题仍然存在。 QWebEngineView 内的 JavaScript 获取操作失败,由于 WebSocket 连接被拒绝,我无法成功连接到远程调试界面。
我仍然无法让获取操作正常工作,但我想出了如何通过远程调试来解决问题。 正如here中所述:“任何 WebEngine 命令行选项都应在 --webEngineArgs 选项之后指定,该选项用于将用户的应用程序特定选项与 WebEngine 的选项分开。”
所以我将其添加到我的代码中:
sys.argv.append('--webEngineArgs')
sys.argv.append('--remote-allow-origins=*')
app = QApplication(sys.argv)