Override HTTP Error Page in QtWebkit

I would like to display the error page in a QWebView . For example, if the server returns a 404 error, QWebView should display its own 404 error of its own instead of the one sent from the server .

I use QWebPage::extension to handle error conditions, and it works well for network errors. However, if the server returns a 404 error and at the same time returns an error page, this page is displayed and the QWebPage::extension method is never called.

Is there a way to get QtWebKit to call an error handler and override the server error page?

+6
source share
2 answers

One note: if you replace the mainFrame content in the handleNetworkFinished () slot, you can see your error page instead of the loaded page if network errors occurred with page elements (for example, external images or scripts).

Another option would be to reimplement QWebPage :: extension () and QWebPage :: supports Extension (), in which case QT Webkit will call your implementation of extension () for page errors and replace the contents of the page with the page that you specified as:

 class WebPage : public QWebPage { Q_OBJECT public: WebPage(QObject *parent = 0); bool extension(Extension extension, const ExtensionOption *option, ExtensionReturn * output); bool supportsExtension(Extension extension) const; }; bool WebPage::extension(Extension extension, const ExtensionOption *option, ExtensionReturn * output) { if(!option || !output) { return false; } if(extension == QWebPage::ErrorPageExtension) { const ErrorPageExtensionOption *errOption = static_cast<const ErrorPageExtensionOption*>(option); QString errPage; errPage = "<html><body><h1>"; errPage += "Page loading error, URL: "; errPage += errOption->url.toString(); errPage += "</h1><h3>Error occurred in the "; switch (errOption->domain) { case QWebPage::QtNetwork: errPage += "QT network layer, code is: "; break; case QWebPage::Http: errPage += "HTTP layer, HTTP error code is: "; break; case QWebPage::WebKit: errPage += "WebKit internals, error code is: "; break; default: errPage += "Unknown domain, error code is: "; } errPage += errOption->error; errPage += "</h3><h4><br>Error text: "; errPage += errOption->errorString; errPage += "</h4></body></html>"; ErrorPageExtensionReturn *errReturn = static_cast<ErrorPageExtensionReturn*>(output); errReturn->baseUrl = errOption->url; errReturn->content = errPage.toUtf8(); // errReturn->contentType = "text/html" // errReturn->encoding = "UTF-8"; // these values are defaults return true; } return false; } bool WebPage::supportsExtension(Extension extension) const { if(extension == QWebPage::ErrorPageExtension) { return true; } return QWebPage::supportsExtension(extension); } 
+2
source

After you skip code for a long time, trying various things, it seems that at least my question solves the following:

 MyWebPageSubclass::MyWebPageSubclass(...) { connect(networkAccessManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(handleNetworkFinished(QNetworkReply*))); // ... } void MyWebPageSubclass::handleNetworkFinished(QNetworkReply *reply) { bool ok = false; int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(&ok); if (ok && httpStatus / 100 != 1 && httpStatus / 100 != 2 && httpStatus / 100 != 3) { if (!supportsExtension(ErrorPageExtension)) { return; } ErrorPageExtensionOption option; option.domain = Http; option.error = httpStatus; option.url = reply->url(); option.errorString = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); ErrorPageExtensionReturn output; if (!extension(ErrorPageExtension, &option, &output)) { return; } mainFrame()->setContent(output.content, output.contentType, output.baseUrl); } } 
+4
source

Source: https://habr.com/ru/post/908442/


All Articles