2011-12-02 4 views
11

Instalación limpia de Qt SDK 1.1.4 en Windows 7 con Visual C++ 2008 SP1; Estoy usando Qt Creator. ¿Por qué este código no carga algunas páginas web?QWebView/Qt WebKit no abrirá algunas páginas SSL; redirigir no permitido?

#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(); 
} 

¿Por qué algunas de las URL no funcionan, y otras sí?

Creo que google.com/www.google.com es especialmente revelador; google.com normalmente redirige a www.google.com. Y gmail.com está redirigiendo a accounts.google.com. ¿WebKit no permite redirigir páginas seguras? Si es así, ¿cómo arreglar eso?

Por cierto, Qt SDK 1.1.4 parece incluir OpenSSL; Noté su presencia en C: \ QtSDK \ Desktop \ Qt \ 4.7.4 \ msvc2008 \ bin \ ssleay32.dll. También observe que algunas páginas parecen funcionar, pero no otras.

EDIT: Otros dos direcciones URL:

b.load(QUrl("https://support.motionview3d.com/help/_media/images/directory.png")); // doesn't work 
b.load(QUrl("https://mail.google.com")); // works 

Una vez más, ambos funcionan bien en otros navegadores web.

Respuesta

16

Probablemente esté recibiendo errores SSL que puede manejar en una ranura. Aunque no es la mejor solución final, puede usar la ranura para ignorar todos los errores de SSL. Hice esto subclasificando 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(); 
} 

La ejecución de este debe producir la salida de depuración de esta manera:

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" 
... 

En el programa final, por supuesto, quieren manejar adecuadamente los errores SSL :)

+1

¿Qué lío? Parece que solo hay dos posibilidades aquí: (1) La especificación HTTP permite un certificado incorrecto al redireccionar u otros casos especiales, pero Qt tiene un error y se niega a acceder a la redirección en primer lugar (está siendo "demasiado estricto"). O (2) Los administradores de Google cometieron un error pero no se dieron cuenta porque Internet Explorer, Firefox, Chrome y otros navegadores principales tienen un serio problema de seguridad. ¿Que está pasando aqui? –

+2

Bueno, parece que Qt es menos tolerante a los errores de SSL que el navegador web promedio.Resulta que el webmaster del servidor que realmente me importa no ha instalado certificados intermedios en el servidor: http://www.sslshopper.com/ssl-certificate-not-trusted-error.html (ver última opción). –

+0

También es posible combinar esto con '' 'examples/network/securesocketclient''' para mostrar estos errores en la interfaz de usuario. –

0

que suelen utilizar la solución de s "Arnold Spence", pero a veces eso no funcionará.

en ese caso simplemente modificar la configuración SSL predeterminado como esto

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); 

Aquí hemos alterado la configuración para toda la aplicación.

Le recomiendo que maneje la señal sslErrors también ..