C++ Qt从QNetworkRequest获取HTTP头

aha*_*mas 0 c++ qt qnetworkaccessmanager http-headers

我正在开发一个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)));
Run Code Online (Sandbox Code Playgroud)

downloadProgressChanged带有此代码的插槽在哪里:

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

(我使用QProgressBar命名progressBar显示进度,QLabel命名labelProgress显示下载的千字节).

我的问题是我无法访问Content-Length标头(int fileSize值为0),因此我无法显示操作的进度.我检查了我的网络服务器上的HTTP标头 - Content-Length工作正常.

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

sug*_*uff 6

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

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

尝试使用QNetworkAccessManager发出请求,然后从它返回的回复中获取所需的标头.有一种特殊方法可以从请求中仅检索标头信息:

QNetworkAccessManager::head(const QNetworkRequest & request)
Run Code Online (Sandbox Code Playgroud)

由于Qt的网络API是异步的,您必须将QNetworkAccessManager的完成(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();
    }
}
Run Code Online (Sandbox Code Playgroud)