如何使用 QWebEngineUrlRequestInterceptor

Posted

技术标签:

【中文标题】如何使用 QWebEngineUrlRequestInterceptor【英文标题】:How to use QWebEngineUrlRequestInterceptor 【发布时间】:2016-07-13 06:06:45 【问题描述】:

我需要在 Qt 应用程序的 WebEngine qml 组件中拦截请求。

我在 QWebEngineUrlRequestInterceptor 上找到了文档,它似乎在这里http://doc.qt.io/qt-5/qwebengineprofile.html#details 和这里http://doc.qt.io/qt-5/qwebengineurlrequestinterceptor.html#details 这样做。但是我还没有找到任何关于如何在 Qt/C++ 中执行此操作的代码示例。

感谢任何帮助。

【问题讨论】:

【参考方案1】:

在这篇文章的帮助下设法解决了这个问题:https://forum.qt.io/topic/69135/how-to-send-network-requests-in-qwebengine/2

这是我连接 QWebEngineUrlRequestInterceptor 的解决方案:

.h 文件

class WebUrlRequestInterceptor : public QWebEngineUrlRequestInterceptor

    Q_OBJECT

public:
    WebUrlRequestInterceptor(QObject *p = Q_NULLPTR);
    void interceptRequest(QWebEngineUrlRequestInfo &info);
;

.cpp 文件

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 文件

WebUrlRequestInterceptor *wuri = new WebUrlRequestInterceptor();
QWebEngineProfile::defaultProfile()->setRequestInterceptor(wuri);

【讨论】:

【参考方案2】:

QWebEngineUrlRequestInterceptor 类为 URL 拦截提供了一个抽象基类,我推荐它来处理自定义协议,(mail://, example:// ....)

让我们通过继承 QWebEngineUrlRequestInterceptor 来实现它:

你的头文件exampleurlschemehandler.h文件:

class ExampleUrlSchemeHandler : public QWebEngineUrlSchemeHandler

    Q_OBJECT
public:
    explicit ExampleUrlSchemeHandler(QObject *parent = 0);
public:

    void requestStarted(QWebEngineUrlRequestJob *request);
;

您的 cpp 文件:

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
    // .....

现在将它安装在您的默认 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));

其他处理HTTP/HTTPS请求的方法是继承QWebEnginePage,并重新实现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);

现在,在你的 QWebEngineView 中设置这个页面。

【讨论】:

在对代码进行一些修复后,它编译并运行,但它没有拦截任何请求。而且它不包括 QWebEngineUrlRequestInterceptor? 对不起,我没有编译代码,我只是附上了一个例子:S。我开始在没有任何信息或文档的情况下在 alpha 版本中使用 Qt 5.6,所以我在我的代码中使用了 schemahandler。相同问题的不同替代方案。不需要使用 QWebEngineUrlRequestInterceptor。在我的情况下,我使用模式处理程序来轻松处理我自己的协议(logospeech://)。我自定义了自己的 QWebEnginePage 来处理 http/https 请求并避免多次重定向。

以上是关于如何使用 QWebEngineUrlRequestInterceptor的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?