Название: POST запрос через QNetworkAccessManager
Отправлено: Quty от Апрель 06, 2013, 00:43
Работаю с API Вконтакте, необходимо загрузить фотографию на сервер. Получаю ссылку, она имеет такой вид: http://cs322519.vk.com/upload.php?act=do_add&mid=96160242&aid=-3&gid=0&hash=c87ebbd3d10060472750b1a1963c946d&rhash=a6e16f727a7d8d11d86a517515506cb6&swfupload=1&api=1&save_big=1&mailphoto=1 Далее необходимо отправить 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(); } Вообще ничего не получилось - программа "вылетает", дойдя до этого места. Я неправильно формирую запрос или дело в чем то еще?
Название: Re: POST запрос через QNetworkAccessManager
Отправлено: kataklysm от Апрель 07, 2013, 14:01
Работаю с API Вконтакте, необходимо загрузить фотографию на сервер. Получаю ссылку, она имеет такой вид: http://cs322519.vk.com/upload.php?act=do_add&mid=96160242&aid=-3&gid=0&hash=c87ebbd3d10060472750b1a1963c946d&rhash=a6e16f727a7d8d11d86a517515506cb6&swfupload=1&api=1&save_big=1&mailphoto=1 Далее необходимо отправить 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().
Название: Re: POST запрос через QNetworkAccessManager
Отправлено: Quty от Апрель 07, 2013, 14:19
Файл(file.close) необходимо закрывать в слоте uploadScreenshotToServerReplyFinished().
Попробовал, результат тот же, да и по-моему нету разницы, ведь данные из файла к моменту отправки запроса на сервер уже прочитаны полностью.
Название: Re: POST запрос через QNetworkAccessManager
Отправлено: Quty от Апрель 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\" в заголовок и все заработало как надо.
|