我一直在尝试使用 QNetworkAccessManager 加载 (ny) https:// 网页,但无法通过:preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *) 信号。当我使用 http:// 加载相同的页面时,它们会正常运行,但有些服务器需要 https://,所以我坚持使用它们。
编辑添加:这是在带有 Qt 5.9.5 的 Ubuntu 18.04 上
我已经连接了大多数错误信号,这些信号没有被发出 - 我只是得到了 encrypted() 和 preSharedKeyAuthenticationRequired() 信号,这对于正在发生的事情是非常不言自明的,但是关于如何前进的文档是... 不足。
所有这些 https:// 页面都可以在 Chrome 中轻松/简单地加载 - 无需密码。
如何让 QNetworkAccessManager 以 Chrome 的方式或类似方式拉取页面?
PageHandler::PageHandler( QObject *parent ) : QObject(parent)
{ connect(&networkManager, SIGNAL(finished(QNetworkReply*)) , SLOT(pageRequestFinished(QNetworkReply*)) );
connect(&networkManager, SIGNAL(encrypted(QNetworkReply*)), SLOT(pageRequestEncrypted(QNetworkReply*)) );
connect(&networkManager, SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError> &)), SLOT(sslErrors(QNetworkReply *, const QList<QSslError> &)) );
getPage( QUrl( "https://google.com/" ) );
}
void PageHandler::getPage( const QUrl &url )
{ QNetworkRequest *request = new QNetworkRequest();
// request.setSslConfiguration( QSslConfiguration::defaultConfiguration() ); this seems to do nothing
request->setHeader( QNetworkRequest::UserAgentHeader, APP_NAME );
request->setUrl( url );
QNetworkReply *r = networkManager.get( *request );
connect( r, SIGNAL(finished()), SLOT(replyFinished()) );
connect( r, SIGNAL(encrypted()), SLOT(replyEncrypted()) );
connect( r, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *)), SLOT(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *)) );
// connect( r, SIGNAL(errorOccurred(QNetworkReply::NetworkError)), SLOT(errorOccurred(QNetworkReply::NetworkError)) ); Qt 5.15+ only
qDebug( QString( "getting page %1" ).arg( url.toString() ) );
}
// Get this for http://
void PageHandler::replyFinished()
{ qDebug( "replyFinished()" );
}
// Get this for https://
void PageHandler::replyEncrypted()
{ qDebug( "replyEncrypted()" );
}
// Never see this
void PageHandler::errorOccurred(QNetworkReply::NetworkError code)
{ qDebug( QString( "wrror occurred %1" ).arg(code) )
}
// Get this for https://
void PageHandler::preSharedKeyAuthenticationRequired( QSslPreSharedKeyAuthenticator *authenticator )
{ qDebug( QString( "preSharedKeyAuthenticationRequired hint '%1'" ).arg( QString::fromUtf8( authenticator->identityHint() ) ) ) // This is empty
authenticator->setIdentity( QByteArray() ); // What to do here, if anything?
authenticator->setPreSharedKey( QByteArray() );
}
// Get this for http://
void PageHandler::pageRequestFinished( QNetworkReply *r )
{ qDebug( "got page" );
QList<QByteArray> hl = r->rawHeaderList();
foreach ( QByteArray ba, hl )
qDebug( QString( "header '%1'").arg( QString::fromUtf8( ba ) ) )
qDebug( QString( "Reply '%1'").arg( QString::fromUtf8( r->readAll() ) ) )
r->deleteLater();
}
// Get this for https:// not for http:// (as expected)
void PageHandler::encrypted( QNetworkReply *r )
{ qDebug( "encrypted" );
if ( r->error() )
qDebug( QString( "encrypted signal error %1 %2" ).arg( r->error() ).arg( r->errorString() ) ); // Never see this
// Nothing shown for the header or body
QList<QByteArray> hl = r->rawHeaderList();
foreach ( QByteArray ba, hl )
qDebug( QString( "Encrypted header '%1'").arg( QString::fromUtf8( ba ) ) );
qDebug( QString( "Encrypted reply '%1'").arg( QString::fromUtf8( r->readAll() ) ) );
// r->ignoreSslErrors(); Makes no difference if this is commented or not
r->deleteLater();
}
void PageHandler::sslErrors(QNetworkReply *r, const QList<QSslError> &e)
{ qDebug( "sslErrors" ); // Never see this
}