原理:发起请求时携带cookie,请求返回时更新服务器返回的cookie,然后存在本地,以供下次启动时获取
存储格式:本demo使用的是key=value;key2=value2的文本格式存储,只是为了方便qml中的ajax请求携带数据,格式可以自定义
sqlite也是被封装了一层,就是单例模式的sql语句执行而已
从sqlite数据库中根据hostname读取cookie
QList<QNetworkCookie> commonHelper::getLocalCookie(QString host)
{
QList<QNetworkCookie> allCookie;
QString cookie;
QString sqlStr = QString("select * from sc_cookies where host='%1';").arg(host);
QSqlQuery *reader = sqliteHelper::getInstance()->executeRead(sqlStr);
if (reader->next())
{
cookie = reader->value("cookie").toString();
}
QStringList cookies = cookie.split(";");
for(int i = 0; i < cookies.size(); ++i)
{
QStringList aCookie = cookies[i].trimmed().split('=');
if(aCookie.size()>1){
allCookie.append(QNetworkCookie(aCookie[0].toUtf8(),aCookie[1].toUtf8()));
}
}
return allCookie;
}
设置cookie到sqlite中
bool commonHelper::setLocalCookie(QString host, QList<QNetworkCookie> allCookie)
{
QString cookie;
QList<QNetworkCookie>::iterator i;
for(i = allCookie.begin(); i != allCookie.end(); ++i){
cookie += (*i).name() + "=" + (*i).value() + ";";
}
int end = cookie.lastIndexOf(';');
if(end>=0)
{
cookie = cookie.mid(0,end);
}
QString sqlStr = QString("replace into sc_cookies (host, cookie) values ('%1','%2');").arg(host).arg(cookie);
int iRet = sqliteHelper::getInstance()->executeQuery(sqlStr);
return 0==iRet;
}
调用时携带cookie
void httpClient::addCookieHeader(QUrl url)
{
QVariant cookie;
if(0==allcookies.size()){
allcookies = commonHelper::getLocalCookie(url.host());
}
cookie.setValue(allcookies);
qDebug()<<"set cookie:"<<cookie;
httpRequest.setHeader(QNetworkRequest::CookieHeader, cookie);
}
void httpClient::get(const QString url)
{
QUrl qUrl(url);
qDebug("http get %s", qPrintable(url));
httpRequest.setUrl(qUrl);
addCookieHeader(qUrl);
networkAccessManager.get(httpRequest);
}
void httpClient::post(const QString url, const QByteArray &data)
{
QUrl qUrl(url);
qDebug("http post %s %s", qPrintable(url), data.toStdString().c_str());
httpRequest.setUrl(qUrl);
addCookieHeader(qUrl);
networkAccessManager.post(httpRequest, data);
}
请求返回中更新cookie
void httpClient::updateCookie(QNetworkReply *reply)
{
allcookies=reply->manager()->cookieJar()->cookiesForUrl(reply->url());
commonHelper::setLocalCookie(reply->url().host(), allcookies);
}
void httpClient::serviceRequestFinished(QNetworkReply *reply)
{
QJsonObject *pJson = nullptr;
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QByteArray data = reply->readAll();
QString str = QString::fromStdString(data.toStdString()).toUtf8();
//更新cookie
updateCookie(reply);
if(reply->error() == QNetworkReply::NoError)
{
QJsonParseError jsonpe;
QJsonDocument jsonDoc = QJsonDocument::fromJson(str.toUtf8(), &jsonpe);
if (jsonpe.error == QJsonParseError::NoError)
{
pJson = new QJsonObject(jsonDoc.object());
}
else
{
QString a = QString(reply->readAll());
qDebug("json error %d", jsonpe.error);
}
}
else
{
qDebug("network error %d", reply->error());
}
reply->deleteLater();
}