You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt向Apache服务器上传文件异常:服务器端文件大小始终为0

问题:Qt上传文件到Apache服务器后文件大小始终为0

我在树莓派上运行Apache服务器,/var/www/html/pic文件夹内存放多个PNG文件,可通过http://192.168.0.23/pic访问,也能通过Qt 6.5的QNetworkAccessManager正常下载所有文件,但上传文件时服务器接收的文件大小始终为0。

Qt上传代码

// Ouvrir le fichier PNG
QFile file(PICPATH_ABS + "TOTO.png");
if (!file.open(QIODevice::ReadOnly)) {
    qDebug() << "Impossible d'ouvrir le fichier";
    return;
}

QUrl url(REMOTE_PIC_PATH + "TOTO.png");
QNetworkRequest request(url);

QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"TOTO.png\""));
filePart.setHeader(QNetworkRequest::ContentLengthHeader, file.size());
filePart.setBodyDevice(&file);

QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
multiPart.append(filePart);

// Envoyer la requête HTTP POST
QNetworkAccessManager manager;
QNetworkReply * reply = manager.post(request, &multiPart);

// Connexion du signal uploadProgress() pour afficher la progression de l'envoi
QObject::connect(reply, &QNetworkReply::uploadProgress, [&](qint64 bytesSent, qint64 bytesTotal) {
    qDebug() << "Sent :" << bytesSent << "on" << bytesTotal;
});

QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec(); // Attendre la fin de la réponse

// Vérifier la réponse du serveur
if (reply->error() != QNetworkReply::NoError) {
    qDebug() << "Error : " << reply->errorString();
} else {
    qDebug() << "Success !";
}

// Nettoyer
file.close();
reply->deleteLater();

控制台输出

Sent: 16384 on 498328
Sent: 498328 on 498328
Sent: 0 on 0
Success !

我已将/var/www/html/pic文件夹配置为可写,以下是具体解决思路:


解决思路

1. 服务器端核心问题:缺少文件接收逻辑

Apache默认不会处理直接POST到静态文件路径的请求,你需要一个后端脚本(如PHP、CGI)来接收并保存上传的文件:

  • 创建PHP处理脚本/var/www/html/pic/upload.php:
    <?php
    $target_dir = "./";
    $target_file = $target_dir . basename($_FILES["file"]["name"]);
    // 验证文件类型
    $fileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    if($fileType != "png") {
        echo "仅支持PNG文件";
        exit;
    }
    if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
        echo "文件上传成功";
    } else {
        echo "上传失败:" . $_FILES["file"]["error"];
    }
    ?>
    
  • 修改Qt代码中的请求URL为http://192.168.0.23/pic/upload.php,而非直接指向目标文件名。

2. Qt代码优化

  • 删除手动设置的ContentLengthHeader,QHttpMultiPart会自动处理该头部,手动设置可能导致长度不匹配:
    // 移除这行代码
    // filePart.setHeader(QNetworkRequest::ContentLengthHeader, file.size());
    
  • 确保QHttpMultiPart的生命周期:将其改为堆对象,避免栈对象提前析构导致数据丢失:
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    multiPart->append(filePart);
    
    QNetworkReply *reply = manager.post(request, multiPart);
    multiPart->setParent(reply); // 让reply销毁时自动清理multiPart
    

3. 权限验证

确保Apache进程(通常为www-data用户)对目标文件夹有完整写入权限:

sudo chown -R www-data:www-data /var/www/html/pic
sudo chmod -R 755 /var/www/html/pic

4. 服务器端调试

  • 查看Apache错误日志定位问题:
    cat /var/log/apache2/error.log
    
  • 用curl测试上传,排除Qt代码问题:
    curl -X POST -F "file=@/本地路径/TOTO.png" http://192.168.0.23/pic/upload.php
    

内容的提问来源于stack exchange,提问作者palador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:42:22