I need to intercept requests made in our WebEngine qml component in our Qt application.
I have found documentation on QWebEngineUrlRequestInterceptor which seems to do just this here http://doc.qt.io/qt-5/qwebengineprofile.html#details and here http://doc.qt.io/qt-5/qwebengineurlrequestinterceptor.html#details. However I haven't found any code examples on how to do this in Qt/C++.
Any help is appreciated.
Managed to puzzle it together with the help of this post: https://forum.qt.io/topic/69135/how-to-send-network-requests-in-qwebengine/2
This is my solution to hook up a QWebEngineUrlRequestInterceptor:
.h file
class WebUrlRequestInterceptor : public QWebEngineUrlRequestInterceptor
{
Q_OBJECT
public:
WebUrlRequestInterceptor(QObject *p = Q_NULLPTR);
void interceptRequest(QWebEngineUrlRequestInfo &info);
};
.cpp file
WebUrlRequestInterceptor::WebUrlRequestInterceptor(QObject *p)
:QWebEngineUrlRequestInterceptor(p)
{
}
void WebUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) {
QString rsrct = "";
switch(info.resourceType()){
case 0:rsrct="ResourceTypeMainFrame = 0, // top level page";break;
case 1:rsrct="ResourceTypeSubFrame, // frame or iframe";break;
case 2:rsrct="ResourceTypeStylesheet, // a CSS stylesheet";break;
case 3:rsrct="ResourceTypeScript, // an external script";break;
case 4:rsrct="ResourceTypeImage, // an image (jpg/gif/png/etc)";break;
case 5:rsrct="ResourceTypeFontResource, // a font";break;
case 6:rsrct="ResourceTypeSubResource, // an other subresource.";break;
case 7:rsrct="ResourceTypeObject, // an object (or embed) tag for a plugin,";break;
case 8:rsrct="ResourceTypeMedia, // a media resource.";break;
case 9:rsrct="ResourceTypeWorker, // the main resource of a dedicated worker.";break;
case 10:rsrct="ResourceTypeSharedWorker, // the main resource of a shared worker.";break;
case 11:rsrct="ResourceTypePrefetch, // an explicitly requested prefetch";break;
case 12:rsrct="ResourceTypeFavicon, // a favicon";break;
case 13:rsrct="ResourceTypeXhr, // a XMLHttpRequest";break;
case 14:rsrct="ResourceTypePing, // a ping request for <a ping>";break;
case 15:rsrct="ResourceTypeServiceWorker, // the main resource of a service worker.";break;
case 16:rsrct="ResourceTypeUnknown";break;
default : rsrct="Unknown type";break;
}
qDebug()<<"\t"<<Q_FUNC_INFO<<":\n\t\t" << "WebUrlRequestInterceptor::interceptRequest " <<info.requestMethod()
<<"\r\n "<<info.requestUrl()<<" "<<rsrct <<"\r\n";
}
main.cpp file
WebUrlRequestInterceptor *wuri = new WebUrlRequestInterceptor();
QWebEngineProfile::defaultProfile()->setRequestInterceptor(wuri);
The QWebEngineUrlRequestInterceptor class provides an abstract base class for URL interception, i recommend it to handle custom protocols, (mail://, example:// ....)
Let's implement it by subclasing QWebEngineUrlRequestInterceptor:
Your header file exampleurlschemehandler.h file:
class ExampleUrlSchemeHandler : public QWebEngineUrlSchemeHandler
{
Q_OBJECT
public:
explicit ExampleUrlSchemeHandler(QObject *parent = 0);
public:
void requestStarted(QWebEngineUrlRequestJob *request);
};
Your cpp file:
ExampleUrlSchemeHandler::ExampleUrlSchemeHandler(QObject *parent) : QWebEngineUrlSchemeHandler(parent){}
void ExampleUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request){
// Abort the request if you want to redirect it or something
request->fail(QWebEngineUrlRequestJob::RequestAborted);
// Get the URL
const QUrl url = request->requestUrl();
// Do amazing thing with your URL
// .....
}
Now install it in your default QWebEngineProfile:
const QString EXAMPLE_SCHEMA_HANDLER = "example://" /* http://, https://, mail:// .... */;
const QWebEngineUrlSchemeHandler* installed = QWebEngineProfile::defaultProfile()->urlSchemeHandler(EXAMPLE_SCHEMA_HANDLER);
if (!installed)
profile()->installUrlSchemeHandler(EXAMPLE_SCHEMA_HANDLER, new WebAppUrlSchemeHandler(this));
Other method, to handle HTTP/HTTPS request is subclassing QWebEnginePage, and reimplementing acceptNavigationRequest():
bool WebAppPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool main) {
// Example: We want to redirect all links clicked by user to native webbrowser
if (type == QWebEnginePage::NavigationTypeLinkClicked)
QDesktopServices::openUrl(url);
}
Now, set this page in your QWebEngineView.