【问题标题】:How do I save cookies with Qt?如何使用 Qt 保存 cookie?
【发布时间】:2023-04-09 08:27:01
【问题描述】:

我正在尝试将我的应用程序生成的 cookie 保存到磁盘位置,例如 C:\Users\Username\AppData\Local\MyCompany\MyApp。我已经实现了一个 webview,并且已经完成了对我的简单浏览器的编码,最后要做的是保存 cookie。

我可以 qDebug() 我从 webapp 获得的 cookie,它们显示 cookie 的格式正确,但我 a) 不确定从那里去哪里 b) 不能 100% 确定如何创建cookiejar 类?

下面我在 MainWindow 构造函数中创建我的 cookiejar 对象

view = new QWebView(this);
jar = new QNetworkCookieJar;
view->page()->networkAccessManager()->setCookieJar(jar);

在我的 replyfinished 槽中,我可以看到回复中包含的 cookie,我尝试保存它,但没有任何反应,也没有收到运行时错误。关于这方面的内容并不多,并且已经看过一些帖子,其中的指令是创建一个子类 QNetworkCookieJar,但之前没有在 Qt/C++ 中创建一个子类。

有没有一种简单的方法来存储 cookie,我不是在寻找任何花哨的东西。 cookie 只是确保在登录页面上勾选了一些复选框。

// SLOT that accepts the read data from the webpage
void MainWindow::slotReplyFinished(QNetworkReply *reply){

    if(reply->isFinished()){
        QVariant variantCookies = reply->header(QNetworkRequest::SetCookieHeader);
        QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie> >(variantCookies);
        qDebug() << "Cookies reply: " << cookies;
        QNetworkCookie cookie; //Create a cookie



        jar = new QNetworkCookieJar;
        //view->page()->networkAccessManager()->setCookieJar(jar);
        jar->setCookiesFromUrl(cookies, reply->request().url());
        //qDebug() << "Saved cookies: " << jar->getAllCookies();
    }

    qDebug() << "Network reply: " << reply->errorString() << reply->error() << reply->request().url();
 }

【问题讨论】:

    标签: c++ qt cookies qnetworkaccessmanager


    【解决方案1】:

    您需要继承 QNetworkCookieJar 并且在该类中您应该实现自己的持久存储。

    class MyNetworkCookieJar : public QNetworkCookieJar {
    
    public: 
    
    bool saveCookiesToDisk() {
    // .. my implementation
    return true; // if i did
    }
    
    bool loadCookiesFromDisk() {
    // .. load from disk
    return false; // if unable to.
    }
    }
    

    Qt 项目中的示例应用程序实现了一个持久的 cookie 存储,这对您来说可能是一个很好的起点:http://qt.gitorious.org/qt/qt/trees/4.8/demos/browser

    查看 cookiejar.h 和 cookiejar.cpp

    【讨论】:

    • 感谢您的快速回复,我会看看,虽然我不完全确定如何实现。看起来所有代码都需要进入头类文件,将其包含在我的 MainWindow.cpp 中,然后我可以调用该函数对吗?
    • 对不起,还有代码块// .. my implementation的部分我不完全确定cookiejar函数实现了这两个目标?
    • 我想我需要重新实现 setCookiesFromUrl() 不太确定怎么做?
    • 看我贴的链接里的cookiejar.cpp文件,有实现,直接用就行了。
    【解决方案2】:

    基于 qt 示例,http://qt.gitorious.org/qt/qt/trees/4.8/demos/browser,我编写了这个类,为我保存和使用一个 cookie。也许它也对你有帮助。请注意,它只保存一个 cookie,而不是 cookie 列表。

    #include "cookiejar.h"
    
    
    CookieJar::CookieJar(QObject *parent)
        : QNetworkCookieJar(parent)
        , m_loaded(false)
    {
    }
    
    void CookieJar::load()
    {
        if (m_loaded)
            return;
    
        QSettings settings;
        settings.beginGroup(QLatin1String("cookies"));
        QList<QNetworkCookie> savedCookies = QNetworkCookie::parseCookies(settings.value("cookies").toByteArray());
    
        for (int j = 0; j < savedCookies.count(); j++)
            insertCookie(savedCookies.at(j));
    
        m_loaded = true;
        emit cookiesChanged();
    }
    
    void CookieJar::save()
    {
        if (!m_loaded)
            return;
    
        QList<QNetworkCookie> cookies = allCookies();
    
        QSettings settings;
        settings.beginGroup(QLatin1String("cookies"));
        settings.setValue("cookies", cookies[0].toRawForm());
    }
    
    QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const
    {
        // This function is called by the default QNetworkAccessManager::createRequest(),
        // which adds the cookies returned by this function to the request being sent.
    
        CookieJar *that = const_cast<CookieJar*>(this);
        if (!m_loaded)
            that->load();
    
        return QNetworkCookieJar::cookiesForUrl(url);
    }
    
    bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
    {
        if (!m_loaded)
            load();
    
        QNetworkCookieJar::setCookiesFromUrl(cookieList, url);
        save();     //Save cookie permanently in setting file.
        emit cookiesChanged();
        return true;
    }
    

    【讨论】:

    • 检查我分享的链接。
    【解决方案3】:

    @Musa 的回答很好,但它只保存了一个 cookie。我建议使用旧 qmlviewer 中的 Qt 实现:http://code.qt.io/cgit/qt/qt.git/tree/tools/qml/qmlruntime.cpp?h=4.7#n438

    代码如下:

    class PersistentCookieJar : public QNetworkCookieJar {
    public:
        PersistentCookieJar(QObject *parent) : QNetworkCookieJar(parent) { load(); }
        ~PersistentCookieJar() { save(); }
    
        virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const
        {
            QMutexLocker lock(&mutex);
            return QNetworkCookieJar::cookiesForUrl(url);
        }
    
        virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
        {
            QMutexLocker lock(&mutex);
            return QNetworkCookieJar::setCookiesFromUrl(cookieList, url);
        }
    
    private:
        void save()
        {
            QMutexLocker lock(&mutex);
            QList<QNetworkCookie> list = allCookies();
            QByteArray data;
            foreach (QNetworkCookie cookie, list) {
                if (!cookie.isSessionCookie()) {
                    data.append(cookie.toRawForm());
                    data.append("\n");
                }
            }
            QSettings settings;
            settings.setValue("Cookies",data);
        }
    
        void load()
        {
            QMutexLocker lock(&mutex);
            QSettings settings;
            QByteArray data = settings.value("Cookies").toByteArray();
            setAllCookies(QNetworkCookie::parseCookies(data));
        }
    
        mutable QMutex mutex;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2017-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多