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
相关产品推荐
相关产品推荐

