QWebView/Qt WebKit не откроет некоторые страницы SSL; перенаправления не разрешены?
Чистая установка Qt SDK 1.1.4 на Windows 7 с Visual С++ 2008 SP1; Я использую Qt Creator. Почему этот код не загружает некоторые веб-страницы?
#include <QtGui/QApplication>
#include <QtWebKit/QWebView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWebView b;
b.load(QUrl("https://gmail.com")); // doesn't work
//b.load(QUrl("https://accounts.google.com")); // works
//b.load(QUrl("https://google.com")); // doesn't work
//b.load(QUrl("https://www.google.com")); // works
b.show();
return a.exec();
}
Почему некоторые URL-адреса не работают, а другие -?
Я думаю, что google.com/www.google.com особенно говорит; google.com обычно перенаправляется на www.google.com. И gmail.com перенаправляется на accounts.google.com. WebKit не позволяет перенаправлять защищенные страницы? Если да, то как это исправить?
Кстати, Qt SDK 1.1.4, похоже, включает OpenSSL; Я заметил его присутствие в C:\QtSDK\Desktop\Qt\4.7.4\msvc2008\bin\ssleay32.dll. Также обратите внимание, что некоторые страницы работают, а не другие.
EDIT: Еще два URL:
b.load(QUrl("https://support.motionview3d.com/help/_media/images/directory.png")); // doesn't work
b.load(QUrl("https://mail.google.com")); // works
Опять же, обе эти функции отлично работают в других веб-браузерах.
Ответы
Ответ 1
Вероятно, вы получаете ошибки SSL, которые вы можете обрабатывать в одном слоте. Хотя это не лучшее окончательное решение, вы можете использовать слот, чтобы игнорировать все ошибки SSL. Я сделал это путем подкласса QWebView
:
qwebview.h:
#ifndef WEBVIEW_H
#define WEBVIEW_H
#include <QWebView>
class WebView : public QWebView
{
Q_OBJECT
public:
WebView(QWidget *parent = 0);
private slots:
void handleSslErrors(QNetworkReply* reply, const QList<QSslError> &errors);
};
#endif // WEBVIEW_H
qwebview.cpp:
#include "webview.h"
#include <QNetworkReply>
#include <QtDebug>
#include <QSslError>
WebView::WebView(QWidget *parent) :
QWebView(parent)
{
load(QUrl("https://gmail.com"));
connect(page()->networkAccessManager(),
SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> & )),
this,
SLOT(handleSslErrors(QNetworkReply*, const QList<QSslError> & )));
}
void WebView::handleSslErrors(QNetworkReply* reply, const QList<QSslError> &errors)
{
qDebug() << "handleSslErrors: ";
foreach (QSslError e, errors)
{
qDebug() << "ssl error: " << e;
}
reply->ignoreSslErrors();
}
main.cpp "
#include <QApplication>
#include "WebView.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
WebView w;
w.show();
return a.exec();
}
Запуск этого процесса должен производить вывод отладки следующим образом:
handleSslErrors:
ssl error: "The host name did not match any of the valid hosts for this certificate"
ssl error: "No error"
ssl error: "No error"
...
В вашей последней программе вы, конечно же, захотите правильно обрабатывать SSL-ошибки:)
Ответ 2
Обычно я использую решение Arnold Spence, но иногда это не работает.
в этом случае просто измените конфигурацию Ssl по умолчанию, например
QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration();
QList<QSslCertificate> cert_list = sslconf.caCertificates();
QList<QSslCertificate> cert_new = QSslCertificate::fromData("CaCertificates");
cert_list += cert_new;
sslconf.setCaCertificates(cert_list);
sslconf.setProtocol(QSsl::AnyProtocol);
QSslConfiguration::setDefaultConfiguration(sslconf);
Здесь мы изменили конфигурацию для всего приложения.
Я рекомендую вам также обрабатывать сигнал sslErrors..