Russian Qt Forum
Ноябрь 23, 2024, 15:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: POST запрос через QNetworkAccessManager  (Прочитано 8481 раз)
Quty
Гость
« : Апрель 06, 2013, 00:43 »

Работаю с API Вконтакте, необходимо загрузить фотографию на сервер. Получаю ссылку, она имеет такой вид:
Цитировать
Далее необходимо отправить POST запрос на этот адрес, в документации сказано следующее:
Цитировать
Приложение формирует POST-запрос на полученный адрес.
Запрос должен включать поле photo, содержащее файл с изображением (JPG, PNG, BMP или GIF)

В программе реализую это так:
Код:
void MainWindow::uploadScreenshotToServer(QUrl uploadUrl)
{
    QFile file("img.png");
    if(file.open(QIODevice::ReadOnly)) {

        QNetworkRequest request;
        request.setUrl(uploadUrl);
        request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
        QByteArray boundary("56gfqgE8VdoO");
        QByteArray data;

        data.append("Content-Type: multipart/form-data; boundary=");
        data.append(boundary);
        data.append("\n\n--");
        data.append(boundary);
        data.append("\n");
        data.append("Content-Disposition: form-data; name=\"photo\"; filename=\"img.png\"\n");
        data.append("Content-Type: image/png\r\n");
        data.append("Content-Transfer-Encoding: binary\n\n");
        data.append(file.readAll());
        data.append("\n--");
        data.append(boundary);
        data.append("--\n");

        reply = manager.post(request, data);
        connect(reply, SIGNAL(finished()), this, SLOT(uploadScreenshotToServerReplyFinished()));
    }
    file.close();
}

В итоге получаю ответ от сервера "{"server":322519,"photo":"[]","hash":"b7f2b773ee8dc8e46d465a4ffb551183"}", т.е. фото вроде как не загрузилось. В документации Qt нашел пример с QHttpMultiPart, решил попробовать так:
Код:
{
    QFile file("img.png");
    if(file.open(QIODevice::ReadOnly)) {
        QNetworkRequest request;
        request.setUrl(uploadUrl);

        QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
        QHttpPart imagePart;
        imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
        imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"photo\""));
        imagePart.setBodyDevice(&file);

        multiPart.append(imagePart);

        reply = manager.post(request, &multiPart);
        connect(reply, SIGNAL(finished()), this, SLOT(uploadScreenshotToServerReplyFinished()));
    }
    file.close();
}

Вообще ничего не получилось - программа "вылетает", дойдя до этого места.
Я неправильно формирую запрос или дело в чем то еще?
« Последнее редактирование: Апрель 06, 2013, 09:14 от Quty » Записан
kataklysm
Гость
« Ответ #1 : Апрель 07, 2013, 14:01 »

Работаю с API Вконтакте, необходимо загрузить фотографию на сервер. Получаю ссылку, она имеет такой вид:
Цитировать
Далее необходимо отправить POST запрос на этот адрес, в документации сказано следующее:
Цитировать
Приложение формирует POST-запрос на полученный адрес.
Запрос должен включать поле photo, содержащее файл с изображением (JPG, PNG, BMP или GIF)

В программе реализую это так:
Код:
void MainWindow::uploadScreenshotToServer(QUrl uploadUrl)
{
    QFile file("img.png");
    if(file.open(QIODevice::ReadOnly)) {

        QNetworkRequest request;
        request.setUrl(uploadUrl);
        request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
        QByteArray boundary("56gfqgE8VdoO");
        QByteArray data;

        data.append("Content-Type: multipart/form-data; boundary=");
        data.append(boundary);
        data.append("\n\n--");
        data.append(boundary);
        data.append("\n");
        data.append("Content-Disposition: form-data; name=\"photo\"; filename=\"img.png\"\n");
        data.append("Content-Type: image/png\r\n");
        data.append("Content-Transfer-Encoding: binary\n\n");
        data.append(file.readAll());
        data.append("\n--");
        data.append(boundary);
        data.append("--\n");

        reply = manager.post(request, data);
        connect(reply, SIGNAL(finished()), this, SLOT(uploadScreenshotToServerReplyFinished()));
    }
    file.close();
}

В итоге получаю ответ от сервера "{"server":322519,"photo":"[]","hash":"b7f2b773ee8dc8e46d465a4ffb551183"}", т.е. фото вроде как не загрузилось. В документации Qt нашел пример с QHttpMultiPart, решил попробовать так:
Код:
{
    QFile file("img.png");
    if(file.open(QIODevice::ReadOnly)) {
        QNetworkRequest request;
        request.setUrl(uploadUrl);

        QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
        QHttpPart imagePart;
        imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
        imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"photo\""));
        imagePart.setBodyDevice(&file);

        multiPart.append(imagePart);

        reply = manager.post(request, &multiPart);
        connect(reply, SIGNAL(finished()), this, SLOT(uploadScreenshotToServerReplyFinished()));
    }
    file.close();
}

Вообще ничего не получилось - программа "вылетает", дойдя до этого места.
Я неправильно формирую запрос или дело в чем то еще?
Файл(file.close) необходимо закрывать в слоте uploadScreenshotToServerReplyFinished().
Записан
Quty
Гость
« Ответ #2 : Апрель 07, 2013, 14:19 »

Файл(file.close) необходимо закрывать в слоте uploadScreenshotToServerReplyFinished().
Попробовал, результат тот же, да и по-моему нету разницы, ведь данные из файла к моменту отправки запроса на сервер уже прочитаны полностью.
Записан
Quty
Гость
« Ответ #3 : Апрель 08, 2013, 11:39 »

Разобрался. Может кому пригодится:
Код:
void MainWindow::uploadScreenshotToServer(QUrl uploadUrl)
{
    QBuffer buffer(&data);
    buffer.open(QIODevice::ReadWrite);
    screenshotPixmap.save(&buffer, "png");
    buffer.close();

    QNetworkRequest request;
    request.setUrl(uploadUrl);

    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart imagePart;
    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
    if(saveMethod->currentIndex() == 0) {
        imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"photo\"; filename=\"img.png\""));
    }
    else if(saveMethod->currentIndex() == 1) {
        imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file1\"; filename=\"img.png\""));
    }
    imagePart.setBody(data);
    multiPart->append(imagePart);

    reply = manager.post(request, multiPart);
    connect(reply, SIGNAL(finished()), this, SLOT(uploadScreenshotToServerReplyFinished()));
    connect(reply, SIGNAL(finished()), multiPart, SLOT(deleteLater()));
}

Ошибка была тут:
Код:
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"photo\"; filename=\"img.png\""));
Добавил filename=\"img.png\" в заголовок и все заработало как надо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 21.