c++ Qt从QNetworkRequest获取HTTP头

C++ Qt get HTTP headers from QNetworkRequest

本文关键字:HTTP 获取 QNetworkRequest Qt c++      更新时间:2023-10-16

我正在开发一个Qt c++应用程序。我需要下载一些文件(可以是大的),并显示下载进度的用户。要执行此任务,我使用以下代码:

QNetworkAccessManager* networkManager = new QNetworkAccessManager();
QNetworkRequest request(fileUrl); //fileUrl is a QUrl variable
QVariant responseLength = request.header(QNetworkRequest::ContentLengthHeader);
int fileSize = responseLength.toInt();
ui->progressBar->setMaximum(fileSize);
QNetworkReply reply = networkManager->get(request);
QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
                 this, SLOT(downloadProgressChanged(qint64,qint64)));

其中downloadProgressChanged为槽位,代码为:

void downloadProgressChanged(qint64 downloaded, qint64 total)
{
    ui->progressBar->setValue(ui->progressBar->value() + 1);
    ui->labelProgress->setText(QString::number((downloaded / 1024)));
}

(我使用名为progressBar的QProgressBar来显示进度,使用名为labelProgress的QLabel来显示下载的kb)。

我的问题是我无法访问内容长度头(int fileSize值为0),因此我无法显示操作的进度。我检查了HTTP头在我的web-server - Content-Length工作正常。

在这个SO问题中,我读到我可以使用QNetworkReply::metaDataChanged()信号,但我如何使用它来显示进度?文档说,信号可以发出时,下载已经开始,但我需要得到标题内容之前,下载将开始-设置我的progressBar

这不是你从请求中获取报头信息的方式:

QNetworkRequest request(fileUrl); //fileUrl is a QUrl variable
QVariant responseLength = request.header(QNetworkRequest::ContentLengthHeader);
int fileSize = responseLength.toInt();
ui->progressBar->setMaximum(fileSize);

尝试用QNetworkAccessManager发出请求,然后从它返回的应答中获得您想要的标头。有一种特殊的方法可以只从请求中检索报头信息:

QNetworkAccessManager::head(const QNetworkRequest & request)

由于Qt的网络API是异步的,你必须将QNetworkAccessManager的finished(QNetworkReply*)信号连接到插槽,并在插槽中获得报头信息。

我是这样做的:

void MainWindow::on_download_button_clicked(){
    QUrl url("http://someurl");
    QNetworkAccessManager * manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(getHeaders(QNetworkReply*)));
    manager->head(QNetworkRequest(url));
}
void MainWindow::getHeaders(QNetworkReply * reply){
    if (reply->operation() == QNetworkAccessManager::HeadOperation){
        int content_length = reply->header(QNetworkRequest::ContentLengthHeader).toInt();
    }
}

您是否尝试过使用readyRead信号?在槽中,你可以准备GUI。应该这样做:

connect(reply, SIGNAL(readyRead()), this, SLOT(updateProgressBar()))