#include "panels/web/ProjectWebView.hpp" #include #include #include #include #include #include namespace geopro::app { namespace { // 把字符串转成安全的 JS 字面量(带引号、转义),用于拼进注入脚本。 QString jsStringLiteral(const QString& s) { // QJsonValue::toJson 不直接给单值字符串;手工转义足够(token 仅含 base64/空格)。 QString out; out.reserve(s.size() + 2); out += QLatin1Char('"'); for (const QChar c : s) { switch (c.unicode()) { case '\\': out += QStringLiteral("\\\\"); break; case '"': out += QStringLiteral("\\\""); break; case '\n': out += QStringLiteral("\\n"); break; case '\r': out += QStringLiteral("\\r"); break; case '\t': out += QStringLiteral("\\t"); break; default: out += c; break; } } out += QLatin1Char('"'); return out; } } // namespace ProjectWebView::ProjectWebView(const QString& token, QWidget* parent) : QWidget(parent) { auto* lay = new QVBoxLayout(this); lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); view_ = new QWebEngineView(this); lay->addWidget(view_, 1); // token 注入:DocumentCreation 阶段把登录 token 写入 localStorage["token"], // 早于嵌入页 SPA 启动脚本,保证其读取鉴权时已就绪。每次 load 都会重新执行。 if (!token.isEmpty()) { QWebEngineScript script; script.setName(QStringLiteral("inject-geopro-token")); script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setWorldId(QWebEngineScript::MainWorld); script.setRunsOnSubFrames(true); script.setSourceCode( QStringLiteral("try{localStorage.setItem('token', %1);}catch(e){}") .arg(jsStringLiteral(token))); view_->page()->scripts().insert(script); } } void ProjectWebView::load(const QString& url) { view_->load(QUrl(url)); } } // namespace geopro::app