QWebView/Qt WebKit не открывает некоторые страницы SSL; редиректы запрещены?

Чистая установка Qt SDK 1.1.4 в Windows 7 с Visual C++ 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 перенаправляет на account.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

Опять же, оба они отлично работают в других веб-браузерах.


person James Johnston    schedule 02.12.2011    source источник


Ответы (2)


Вы, вероятно, получаете ошибки 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 :)

person Arnold Spence    schedule 03.12.2011
comment
Что за беспорядок? Похоже, здесь есть только две возможности: (1) Спецификация HTTP допускает неверный сертификат при перенаправлении или других особых случаях, но Qt имеет ошибку и отказывается получить доступ к перенаправлению в первую очередь (это слишком строго). Или (2) администраторы Google допустили ошибку, но не заметили, потому что Internet Explorer, FireFox, Chrome и другие основные браузеры имеют серьезную дыру в безопасности. Что тут происходит? - person James Johnston; 05.12.2011
comment
Что ж, похоже, что Qt менее терпим к ошибкам SSL, чем средний веб-браузер. Оказывается, веб-мастер на сервере, о котором я действительно беспокоюсь, не установил промежуточные сертификаты на сервере: sslshopper.com/ssl-certificate-not-trusted-error.html (см. последний вариант). - person James Johnston; 05.12.2011
comment
Также возможно объединить это с examples/network/securesocketclient для отображения этих ошибок в пользовательском интерфейсе. - person Sebastian Wagner; 11.03.2014

Я обычно использую решение "Арнольда Спенса", но иногда это не работает.

в этом случае просто измените конфигурацию 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.

person Midhun    schedule 28.10.2015
comment
Верхний блок кода разрешает ошибки? Могу ли я открывать защищенные страницы после добавления этого блока? Где я должен добавить этот код? Пожалуйста, направь меня. - person Pankaj Vavadiya; 30.12.2018