Qtwebkit持久性Cookie不起作用

时间:2014-07-25 10:49:47

标签: qt cookies webkit qwebview qnetworkaccessmanager

我正在尝试在基于Qtwebkit的浏览器中实现持久性以保持节。我扩展了QNetworkCookieJar。我没有覆盖任何文件但只添加了一个保存和加载功能。这些函数被称为explisitly。 我收到以下错误。该代码取自Qt5.1示例中的brower代码。

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);

2 个答案:

答案 0 :(得分:0)

在保存或加载到QSettings之前,您必须先调用qRegisterMetaTypeStreamOperators<QList<QNetworkCookie>>("QList<QNetworkCookie>")

答案 1 :(得分:0)

您需要使用 qRegisterMetaTypeStreamOperators 并定义流运算符。

这是一个保存QList&lt; QNetworkCookie&GT;键入cookie。在头部声明流操作符:

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);
}