HTTP-Client

Demonstriert einen einfachen HTTP-Client.

Dieses Beispiel zeigt, wie ein einfacher HTTP-Client Dateien von entfernten Hosts abrufen kann.

Die Hauptarbeit in diesem Beispiel wird in der Klasse HttpWindow geleistet. Daher werden wir uns darauf konzentrieren.

reply.reset(qnam.get(QNetworkRequest(url)));

Mit Hilfe von QNetworkAccessManager beginnen wir mit dem Herunterladen einer Ressource, auf die url verweist. Wenn Sie mit dieser Funktion oder der verwendeten Funktion QNetworkAccessManager::get() nicht vertraut sind oder sich einfach näher damit befassen möchten, werfen Sie einen Blick in die Dokumentation zu dieser Funktion sowie in die Dokumentation zu QNetworkReply und QNetworkRequest.

connect(reply.get(), &QNetworkReply::finished, this, &HttpWindow::httpFinished);
connect(reply.get(), &QIODevice::readyRead, this, &HttpWindow::httpReadyRead);
#if QT_CONFIG(ssl)
connect(reply.get(), &QNetworkReply::sslErrors, this, &HttpWindow::sslErrors);
#endif

Oben haben wir einige der Signale der Antwort mit Slots in der Klasse verbunden. Diese Slots kümmern sich sowohl um die eingehenden Daten als auch um den Abschluss des Downloads und die Behandlung von Fehlern.

connect(reply.get(), &QIODevice::readyRead, this, &HttpWindow::httpReadyRead);

Was die Verarbeitung der eingehenden Daten betrifft, so verarbeiten wir die eingehenden Daten in QNetworkReply::readyRead() statt in QNetworkReply::finished(), da wir die maximale Downloadgröße einer möglichen Eingabe nicht kennen und den Speicher eines Computers, der das Beispielprogramm ausführen könnte, nicht erschöpfen wollen.

void HttpWindow::httpReadyRead()
{
    // This slot gets called every time the QNetworkReply has new data.
    // We read all of its new data and write it into the file.
    // That way we use less RAM than when reading it at the finished()
    // signal of the QNetworkReply
    if (file)
        file->write(reply->readAll());
}

Dann schreiben wir die Daten in die Datei, wenn sie ankommen. Das ist zwar weniger bequem, aber die Anwendung wird in der Spitze weniger Speicher verbrauchen!

connect(reply.get(), &QNetworkReply::sslErrors, this, &HttpWindow::sslErrors);

Mit dem Signal QNetworkReply::sslErrors() können wir auch Fehler behandeln, die während des TLS-Handshakes bei der Verbindung zu sicheren Websites (d. h. HTTPS) auftreten können.

void HttpWindow::sslErrors(const QList<QSslError> &errors)
{
    QString errorString;
    for (const QSslError &error : errors) {
        if (!errorString.isEmpty())
            errorString += '\n';
        errorString += error.errorString();
    }

    if (QMessageBox::warning(this, tr("TLS Errors"),
                             tr("One or more TLS errors has occurred:\n%1").arg(errorString),
                             QMessageBox::Ignore | QMessageBox::Abort)
        == QMessageBox::Ignore) {
        reply->ignoreSslErrors();
    }
}

In diesem Beispiel wird dem Benutzer ein Dialog angezeigt, in dem er wählen kann, ob er die Fehler ignorieren will oder nicht.

QNetworkReply::NetworkError error = reply->error();
const QString &errorString = reply->errorString();
if (error != QNetworkReply::NoError) {
    QFile::remove(fi.absoluteFilePath());
    // For "request aborted" we handle the label and button in cancelDownload()
    if (!httpRequestAborted) {
        statusLabel->setText(tr("Download failed:\n%1.").arg(errorString));
        downloadButton->setEnabled(true);
    }
    return;
}

Wenn ein Fehler auftritt, sendet QNetworkReply das Signal QNetworkReply::errorOccurred(), gefolgt von dem Signal QNetworkReply::finished(). In diesem Beispiel stellen wir nur eine Verbindung zu letzterem her. Wir behandeln jeden potenziellen Fehler im entsprechenden Slot, indem wir die Datei löschen, in die wir geschrieben haben, und den Fehler mit unserem Statuslabel anzeigen.

connect(&qnam, &QNetworkAccessManager::authenticationRequired,
        this, &HttpWindow::slotAuthenticationRequired);

Wenn Sie eine Verbindung zu einer Website herstellen, die HTTP-Authentifizierung verwendet, können Sie fehlende Anmeldedaten behandeln, wenn die Website sie anfordert, vorausgesetzt, Sie haben die zu verwendenden Anmeldedaten nicht im Voraus angegeben. Mit QNetworkAccessManager tun wir dies in einem Slot, der mit dem Signal QNetworkAccessManager::authenticationRequired() verbunden ist. Wir stellen diese Verbindung einmal im Konstruktor her.

void HttpWindow::slotAuthenticationRequired(QNetworkReply *, QAuthenticator *authenticator)
{
    QDialog authenticationDialog;
    Ui::Dialog ui;
    ui.setupUi(&authenticationDialog);
    authenticationDialog.adjustSize();
    ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm(), url.host()));

    // Did the URL have information? Fill the UI.
    // This is only relevant if the URL-supplied credentials were wrong
    ui.userEdit->setText(url.userName());
    ui.passwordEdit->setText(url.password());

    if (authenticationDialog.exec() == QDialog::Accepted) {
        authenticator->setUser(ui.userEdit->text());
        authenticator->setPassword(ui.passwordEdit->text());
    }
}

In diesem Beispiel wird ein Dialog angezeigt, in dem der Benutzer entweder einen Benutzernamen und ein Passwort eingeben oder die Anfrage abbrechen kann. Bei einem Abbruch wird die Anfrage abgebrochen.

Beispielprojekt @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.