为什么上传图片时无法获得响应数据?

时间:2012-11-26 01:02:12

标签: image qt upload qnetworkaccessmanager

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

@jdi,这是一个问题,现在我得到“?作为qDebug()<< rep-> 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< b.size(); i ++){         qDebug()<< (焦炭)b.at(ⅰ);     } 有没有办法将整个bytearray转换为Qstring,因为我只得到一些符号

? 3,ÉE,V c D? ? ÔâCöf§ 应该是“这是一个测试1”

1 个答案:

答案 0 :(得分:2)

显然,根据您的评论,您的问题是您不止一次地阅读了所有的响应对象。响应对象是一个顺序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();
}