QHttpMultiPart:将文件发布到 PHP 脚本

Posted

技术标签:

【中文标题】QHttpMultiPart:将文件发布到 PHP 脚本【英文标题】:QHttpMultiPart: post files to PHP script 【发布时间】:2013-06-21 12:19:14 【问题描述】:

我正在使用 Qt 5 并正在努力处理分段上传。我的脚本尽可能接近docs:

 QUrl testUrl("http://localhost/upload/test.php");
 QNetworkRequest request(testUrl);


 QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

 QString preview_path  = "C:/preview.jpg";
 QHttpPart previewPathPart;
 previewPathPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_path\""));
 previewPathPart.setBody(preview_path.toLatin1());

 QHttpPart previewFilePart;
 previewFilePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant( "image/jpeg"));
 previewFilePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\""));
 QFile *file = new QFile(preview_path);

 if (!file->exists()) 
     emit error(tr("Upload Error. File does not exist: ") + preview_path);
     return;
 
 file->open(QIODevice::ReadOnly);
 previewFilePart.setBodyDevice(file);
 file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart

 multiPart->append(previewPathPart);
 multiPart->append(previewFilePart);

 reply = networkManager->post(request, multiPart);
 multiPart->setParent(reply); // delete the multiPart with the reply

 connect(reply, SIGNAL(finished()),
          this, SLOT  (uploadReply()));

 connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
          this, SLOT  (uploadError(QNetworkReply::NetworkError)));

 connect(reply, SIGNAL(uploadProgress(qint64, qint64)),
          this, SLOT  (uploadProgress(qint64, qint64)));

然后我的 uploadReply() 槽只打印回复:

QString data = (QString) reply->readAll();
qDebug() << data;

我已使上传脚本尽可能简单,并在 XAMPP 中使用 Apache/2.2.21 和 PHP 5.3.8 运行。我的upload_max_filesize和post_max_size都是1000M。

echo "preview_path: " . (isset($_POST['preview_path']) ? $_POST['preview_path'] : "not set") . "\r\n";
echo "preview_file exists: " . (isset($_POST['preview_file']) ?  "true" : "false" ). "\r\n";
echo '$_FILES: ';
print_r($_FILES);
echo "preview_file content: " . $_POST['preview_file'];

我的进度槽显示了大致正确的上传字节数。

但输出显示:

 preview_path: C:/preview.jpg
 preview_file exists: true
 $_FILES: Array
 (
 )
 preview_file content: ????

似乎字节是作为 $_POST 变量而不是应该作为 $_FILE 提交的? apache日志中没有错误。我该如何调试?

【问题讨论】:

【参考方案1】:

解决了!

感谢this question 的提示 - 我在 QHttpPart 的内容配置中添加了“文件名”,现在它可以按预期上传。我认为文件名是可选的,但在这种情况下似乎有效。希望这对其他人有帮助!

QString preview_name = "preview.jpg";

QHttpPart previewFilePart;
previewFilePart.setHeader(QNetworkRequest::ContentTypeHeader,    QVariant("image/jpeg"));
previewFilePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\"; filename=\""+ preview_name + "\""));

【讨论】:

我的 PHP 是这样说的:Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 有没有办法调试这个?

以上是关于QHttpMultiPart:将文件发布到 PHP 脚本的主要内容,如果未能解决你的问题,请参考以下文章

QT QHttpMultiPart上传图片

Qt使用QHttpMultiPart发送文件的方法

QFile可以把自己的Parent设置成QHttpMultiPart,今天真是开了眼界了~

使用 NetworkManager 上传文件不起作用

为什么上传到谷歌硬盘时没有设置文件名?

是否应该学习qt源码(碰到问题的时候,或者文档对函数描述不清楚的时候,可以看一下)