如何告诉QWebPage不要加载特定类型的资源?

17
如何告诉QWebPage不加载特定类型的资源,例如js、css或png?
3个回答

31
解决方案是扩展 QNetworkAccessManager 类并重写它的虚拟方法 QNetworkAccessManager :: createRequest 。在我们的实现中,我们检查所请求的URL的路径,如果它不是我们想要下载的路径,我们创建并交出一个空请求而不是真正的请求。 下面是一个完整的、可行的示例。
#include <QApplication>
#include <QUrl>

#include <QtWebKit/QWebPage>
#include <QtWebKit/QWebFrame>

#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QDebug>


class NAM : public QNetworkAccessManager {

    Q_OBJECT

protected:

    virtual QNetworkReply * createRequest(Operation op,
                                          const QNetworkRequest & req,
                                          QIODevice * outgoingData = 0) {

        if (req.url().path().endsWith("css")) {
            qDebug() << "skipping " << req.url();
            return QNetworkAccessManager::createRequest(QNetworkAccessManager::GetOperation,
                                                        QNetworkRequest(QUrl()));
        } else {
            return QNetworkAccessManager::createRequest(op, req, outgoingData);
        }
    }
};


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWebPage page;
    NAM nam;

    page.setNetworkAccessManager(&nam);
    page.mainFrame()->load(QUrl("http://google.com"));

    app.exec();
}

#include "main.moc"

有没有一种方法可以通过内容类型而不是扩展名来检查? - Zelid
1
@Zelid 是的。请查看QNetworkRequest::header()QNetworkReply::header() - Piotr Dobrogost
由于Qt放弃了WebKit并转而使用Chromium,因此QtWebEngine和QtWebView不再与QNetworkAccessManager交互:https://doc.qt.io/qt-5/qtwebenginewidgets-qtwebkitportingguide.html#qt-webengine-does-not-interact-with-qnetworkaccessmanager - cydoc

0

我其实也在为同样的问题苦恼,Piotr 的解决方案假设 URL 带有文件扩展名,但不幸的是这并不总是正确的。

虽然可以获取 MIME 类型,但只能在获取响应后才能获取,这太晚了。

我们尝试获取请求资源的元素上下文,比如说如果是 <img> 元素或者用于获取 CSS 的 <link>,但是 req.originatingObject() 只会给我们一个 QWebFrame。我知道在 Mozilla 代码中是可以实现的。

顺便说一句,关闭JavaScript自动加载图片将防止加载图像和脚本。


1
你可以尝试发送一个 HEAD 请求来获取响应头,以便检查 Content-Type 响应头并根据其值做出决策。 - Piotr Dobrogost

-1
如果您的目标是防止网页更改,您可以查看 QWebPage 中的 virtual bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type);。您可以检查请求并返回 false,以防止请求被发送。

2
这是错误的,原因与hmuelner的答案相同。根据文档,“每当WebKit通过指定的导航类型type请求将帧导航到由请求指定的资源时,都会调用此函数。” - Piotr Dobrogost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接