Qtwebkit 持久性 Cookie 不起作用
Posted
技术标签:
【中文标题】Qtwebkit 持久性 Cookie 不起作用【英文标题】:Qtwebkit persistence Cookie is not working 【发布时间】: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);
【问题讨论】:
【参考方案1】:在保存或加载到 QSettings 之前,您必须调用 qRegisterMetaTypeStreamOperators<QList<QNetworkCookie>>("QList<QNetworkCookie>")
。
【讨论】:
【参考方案2】:您需要使用qRegisterMetaTypeStreamOperators并定义流操作符。
这里是一个保存QList
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);
【讨论】:
以上是关于Qtwebkit 持久性 Cookie 不起作用的主要内容,如果未能解决你的问题,请参考以下文章