1.需求:产品需要嵌入某路由器控制界面,但是想隐藏路由器的品牌信息。
先看看效果图:
JS注入前:
JS注入后
2.C++代码,请看代码注释:
#include#include #include #include #include #include #include #include #include #include #include QUrl commandLineUrlArgument() { const QStringList args = QCoreApplication::arguments(); for (const QString& arg : args.mid(1)) { if (!arg.startsWith(QLatin1Char('-'))) return QUrl::fromUserInput(arg); } return QUrl(QStringLiteral("http://tplogin.cn/login.htm")); } int main(int argc, char* argv[]) { QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "7777"); // 设置远程调试环境变量 QWebEngineView view; view.setUrl(commandLineUrlArgument()); QWebEngineProfile* engineProfile = view.page()->profile(); engineProfile->clearHttpCache(); // 清理缓存 engineProfile->clearAllVisitedLinks(); // 清理浏览记录 engineProfile->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);// 会话和持久性cookie都存储在内存中 engineProfile->setHttpCacheType(QWebEngineProfile::NoCache);// 禁用内存和磁盘缓存。 QWebEngineCookieStore* pCookie = engineProfile->cookieStore(); pCookie->deleteAllCookies(); // 清理cookie pCookie->deleteSessionCookies(); // 清理会话cookie // 在DocumentReady的时候注入js代码 QFile file("test.js"); if (file.open(QIODevice::ReadOnly)) { QString content = file.readAll(); file.close(); QWebEngineScript script; script.setSourceCode(content); script.setWorldId(QWebEngineScript::MainWorld); script.setInjectionPoint(QWebEngineScript::DocumentReady); view.page()->profile()->scripts()->insert(script); } // QWebEngineView开始加载的时候 QObject::connect(&view, &QWebEngineView::loadStarted, [&view] { qDebug() << "loadStarted"; }); // QWebEngineView加载完成的时候 QObject::connect(&view, &QWebEngineView::loadFinished, [&view] { // 注意此处需要延时再执行js操作,否则获取不到文档对象。 QTimer::singleShot(500, [&view] { qDebug() << "loadFinished" << view.title(); view.page()->runJavaScript("$('#menu-advanced-running-status-li a').click()"); view.show(); }); }); view.resize(1024, 750); view.show(); return app.exec(); }
3.test.js代码
// test.js
// 获取head标签,插入style标签,此处css的作用是隐藏界面上的一系列元素
var head = document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
head.appendChild(style);
var css = "
body > div.login-banner > a {display: none;}rn
body > div.login-banner > h1 {padding-left: 156px;}rn
body > div.top-banner {display: none;}rn
body > div.user-info {display: none;}rn
body > div.top-tip {display: none;}rn
#menu-advanced-homepage-li {display: none;}rn
#func-advanced > div.home-page-main > div.wireless-info {display: none;}rn
#func-advanced > div.home-page-main > div.system-topo-info > div.system_info_panel > div.content > div:nth-child(4) {display: none;}rn
#menu-advanced-ap-manager-li {display: none;}rn
#menu-advanced-mesh-manage-li {display: none;}rn
#menu-advanced-advanced-li > div > ul > li:nth-child(5) {display: none;}rn
#menu-advanced-sys-tools-li > div > ul > li.sec.sec-fst {display: none;}rn
#menu-advanced-sys-tools-li > div > ul > li:nth-child(6) {display: none;}rn
#menu-wizard {display: none;}rn
#menu-footer {display: none;}rn
";
style.innerHTML = css;
4.注意QWebEngineView::loadFinished信号后延时了500ms再去执行js,否则获取不到文档对象。此处有个较为优雅的处理方法,就是在注入的js中再调用C++的方法,我的其它项目这样做过。



