为啥上传图片时收不到响应数据?

Posted

技术标签:

【中文标题】为啥上传图片时收不到响应数据?【英文标题】:Why do I not get response data when uploading an image?为什么上传图片时收不到响应数据? 【发布时间】:2012-11-26 01:02:12 【问题描述】:

我正在编写一个图像上传小部件,它将数据发送到 php 脚本并从 PHP 脚本获取新上传的文件名作为 http 响应。

@jdi,这是一个问题,现在我得到“?”作为 qDebug() readAll() 的响应,所以第一个 readAll 会清除缓冲区。

QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
image->save(&buffer, "JPG");

QNetworkAccessManager *http=new QNetworkAccessManager(this);
QNetworkRequest r(QUrl("http://domain/test.php"));

QString bound="---------------------------723690991551375881941828858";
QByteArray data(QString("--"+bound+"\r\n").toAscii());
data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"file\"; filename=\"test.jpg\"\r\n";
data += "Content-Type: image/JPG\r\n\r\n";
data += bytes;
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"desc\"\r\n\r\n";
data += "Description for my image here :)\r\n";
data += "\r\n";
r.setRawHeader(QString("Accept-Encoding").toAscii(), QString("gzip,deflate").toAscii());
r.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
r.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());

rep = http->post(r,data);
connect(http,SIGNAL(finished(QNetworkReply*)),this,SLOT(uploadFinished(QNetworkReply*)));

还有回调函数:

void UploadWidget::uploadFinished(QNetworkReply* r)

    r->deleteLater();
    if(r->error() == QNetworkReply::NoError) 
        QByteArray data = r->readAll();
        //QString s = r->readAll(); solved - readAll clears the buffer :)
    

我迭代了 QByteArray b = rep->readAll(); for (int i = 0 ; i

? 3、ÉE、VcD? ? ÔâCöf§ 应该是“1这是一个测试1”

【问题讨论】:

您是否真的在您的插槽中调用了两次readAll,或者这只是您尝试执行此操作的两种不同方式的示例,但它们都是空的? 呃,这是我犯的一个问题,现在它不再是空字符串了,我得到“?”作为 qDebug() 的响应 readAll(); 好的,现在我用 QByteArray b = rep->readAll(); for (int i = 0 ; i 【参考方案1】:

显然,从您的 cmets 来看,您的问题是您多次读取所有响应对象。响应对象是一个顺序 IO 对象,因此一旦您读取它,它就消失了。

QNetworkReply 是一个顺序访问的 QIODevice,这意味着一旦 从对象中读取数据,设备不再保留。

读取一次以获取 QByteArray。您可以将其转换为 QString。

QByteArray data = r->readAll();
QString dataStr(data);
qDebug() << dataStr;

另外需要注意的是,您不应该在每次上传调用中都创建一个全新的 QNetworkAccessManager。您每次都在泄漏它,并且几乎错过了这样一个事实,即为整个应用程序保留一个会自动为您排队多个请求。为您的整个应用程序创建一个并共享它。

另外,您可能想考虑使用QHttpMultipart version of the post method,因为它似乎是一种更简洁的方式来设置所有标题。您几乎可以复制给定的方法,用于发布 jpeg:

QHttpMultipart JPEG post example


更新

读取数据问题的实际原因是这个标题:

r.setRawHeader(QString("Accept-Encoding").toAscii(), 
               QString("gzip,deflate").toAscii());

它告诉服务器以 gzip 压缩的形式发回结果。您最终阅读的内容必须首先解压缩。只需删除该标头,您应该会收到纯文本测试响应。

测试

receiver.h

#include <QObject>

class QNetworkReply;

class Receiver : public QObject

    Q_OBJECT
public:
    explicit Receiver(QObject* parent = 0);
public slots:
    void finished(QNetworkReply*);
;

main.cpp

#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>

#include "receiver.h"

Receiver::Receiver(QObject *parent)
    : QObject(parent)


void Receiver::finished(QNetworkReply *reply) 
    reply->deleteLater();
    QByteArray data = reply->readAll();
    qDebug() << data;


int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);

    QNetworkAccessManager net;
    Receiver rec;

    net.connect(&net, SIGNAL(finished(QNetworkReply*)),
                &rec, SLOT(finished(QNetworkReply*)));

    QNetworkRequest r(QUrl("http://poki.ba/test.html"));
    r.setHeader(r.ContentTypeHeader, QVariant("multipart/form-data;"));
    r.setHeader(r.ContentLengthHeader, QVariant("100"));
//    r.setRawHeader(QString("Accept-Encoding").toAscii(),
//                   QString("gzip,deflate").toAscii());

    net.post(r, QByteArray());

    return a.exec();

【讨论】:

我仍然收到“?” (带引号):(代码:rep->deleteLater(); if(rep->error() == QNetworkReply::NoError) QByteArray data = r->readAll(); QString dataStr(data); qDebug() 您是否使用独立的 html 文件测试了这个 PHP 脚本,以确保它确实返回了适当的数据? pastebin.com/6uxPKY6L 测试网址:poki.ba/test.html 调试:“?” (带引号) 哇 tnx (kudo++)++ !我使用了一个博客的 sn-p,我在其他示例中发现了相同的标题,这对我来说很奇怪,但没有考虑过。 如果此答案解决了您的问题,请不要忘记打勾!不客气!

以上是关于为啥上传图片时收不到响应数据?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在论坛上传图片附件时总是有个来自网页的提示

记录alamofire上传图片请求和响应

php为啥上传图片会失败

java上传图片的图片为啥在tomcat下,我想存在项目的upload下

为啥我不能从我自己的 iOS 应用程序将图片上传到我粘贴的事件?

我的论坛上传图片为啥压缩太厉害?