【问题标题】:Qtwebkit persistence Cookie is not workingQtwebkit 持久性 Cookie 不起作用
【发布时间】:2014-07-25 10:49:47
【问题描述】:

我正在尝试在基于 Qtwebkit 的浏览器中实现持久性以进行部分保存。我已经扩展了 QNetworkCookieJar。我没有覆盖任何文件,只是添加了一个保存和加载功能。这些函数被明确地调用。 我收到以下错误。代码取自 Qt5.1 示例中的浏览器代码。

QVariant::save: unable to save type 'QList<QNetworkCookie>' (type id: 1038).

我做错了什么吗..请帮助...附上我的 QNetworkCookie 实现如下

static const unsigned int JAR_VERSION = 23;
#if 1
QT_BEGIN_NAMESPACE

QDataStream &operator<<(QDataStream &stream, const QList<QNetworkCookie> &list)
{
    stream << JAR_VERSION;
    stream << quint32(list.size());
    for (int i = 0; i < list.size(); ++i)
        stream << list.at(i).toRawForm();
    return stream;
}

QDataStream &operator>>(QDataStream &stream, QList<QNetworkCookie> &list)
{
    list.clear();

    quint32 version;
    stream >> version;

    if (version != JAR_VERSION)
        return stream;

    quint32 count;
    stream >> count;
    for(quint32 i = 0; i < count; ++i)
    {
        QByteArray value;
        stream >> value;
        QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(value);
        if (newCookies.count() == 0 && value.length() != 0) {
            qWarning() << "CookieJar: Unable to parse saved cookie:" << value;
        }
        for (int j = 0; j < newCookies.count(); ++j)
            list.append(newCookies.at(j));
        if (stream.atEnd())
            break;
    }
    return stream;
}
QT_END_NAMESPACE
#endif

CookieJar::CookieJar(QObject *parent)
    : QNetworkCookieJar(parent)
{
    load();
}

CookieJar::~CookieJar()
{
    save();
}

void CookieJar::load()
{
    QSettings cookieSettings("./cookies_dir/Browser/cookies.ini", QSettings::IniFormat);
    setAllCookies(qvariant_cast<QList<QNetworkCookie> >(cookieSettings.value(QLatin1String("cookies"))));
}
void CookieJar::save()
{
//    purgeOldCookies();
    QString directory = "./cookies_dir/Browser";
    if (!QFile::exists(directory)) {
        QDir dir;
        dir.mkpath(directory);
    }
    QSettings cookieSettings(directory + QLatin1String("/cookies.ini"), QSettings::IniFormat);
    QList<QNetworkCookie> cookies = allCookies();
    qWarning("\n\n+=======================================================+\n\n");
    for (int i = cookies.count() - 1; i >= 0; --i) {
        qWarning()<< cookies.at(i).domain();
        qWarning()<< cookies.at(i).name();
        if (cookies.at(i).isSessionCookie())
            cookies.removeAt(i);
    }
    qWarning("\n\n+=======================================================+\n\n");

    cookieSettings.setValue(QLatin1String("cookies"), QVariant::fromValue<QList<QNetworkCookie> >(cookies));
}

void CookieJar::purgeOldCookies()
{
    QList<QNetworkCookie> cookies = allCookies();
    if (cookies.isEmpty())
        return;
    int oldCount = cookies.count();
    QDateTime now = QDateTime::currentDateTime();
    for (int i = cookies.count() - 1; i >= 0; --i) {
        if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now)
            cookies.removeAt(i);
    }
    if (oldCount == cookies.count())
        return;
    setAllCookies(cookies);
}

bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
{
    qWarning()<< url;
    return QNetworkCookieJar::setCookiesFromUrl(cookieList, url);
}

我已经使用下面的代码注册了 CookieJar。

   jar = new CookieJar(this);
    webView->page()->networkAccessManager()->setCookieJar(jar);

【问题讨论】:

    标签: qt cookies webkit qwebview qnetworkaccessmanager


    【解决方案1】:

    在保存或加载到 QSettings 之前,您必须调用 qRegisterMetaTypeStreamOperators&lt;QList&lt;QNetworkCookie&gt;&gt;("QList&lt;QNetworkCookie&gt;")

    【讨论】:

      【解决方案2】:

      您需要使用qRegisterMetaTypeStreamOperators并定义流操作符。

      这里是一个保存QList类型cookies的例子。在标题中声明流操作符:

      class cookieJar: public QNetworkCookieJar
      {
          bool save(const QUrl& url);
          bool load(const QUrl& url);
      }
      QDataStream &operator<<(QDataStream &out, const QNetworkCookie &cookie);
      QDataStream &operator>>(QDataStream &in, QNetworkCookie &cookie);
      

      在 cpp 文件中,您可以执行以下操作:

      CookieJar::CookieJar(QObject* parent) :
          QNetworkCookieJar(parent)
      {
          qRegisterMetaTypeStreamOperators<QNetworkCookie>("QNetworkCookie");
      }
      
      bool CookieJar::save(const QUrl &url)
      {
          QList<QNetworkCookie> cookies = cookiesForUrl(url);
          QSettings cookieSettings;
          for(auto cookie : cookies)
          {
              cookieSettings.setValue(cookie.name(), QVariant::fromValue(cookie));
          }
      }
      
      bool CookieJar::load(const QUrl &url)
      {
          QSettings cookieSettings;
      
          // empty list created here
          QList<QNetworkCookie> cookies;
          // retrieve all keys from cookies.ini
          QStringList keys = cookieSettings.allKeys();
          for(auto key: keys)
          {
              QNetworkCookie cookie = qvariant_cast<QNetworkCookie>(cookieSettings.value(key, QVariant()));
              cookies.append(cookie);
          }
          setCookiesFromUrl(cookies, url);
          return true;
      }
      
      QDataStream &operator<<(QDataStream &out, const QNetworkCookie &cookie)
      {
          out << cookie.toRawForm();
      }
      
      QDataStream &operator>>(QDataStream &in, QNetworkCookie &cookie)
      {
          QByteArray raw_data;
          in >> raw_data;
          QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(raw_data);
          cookie = cookies.at(0);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-05
        相关资源
        最近更新 更多