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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QT Post-запрос  (Прочитано 29361 раз)
secatorr
Гость
« : Сентябрь 07, 2011, 00:26 »

Коллеги! Подскажите, как правильно делать POST-запрос на сервак через QNetworkAccessManager...
Вопрос уже задавался, много читал, но уже голова кругом.
Вот такой код вкратце:
Код:
QByteArray params;
    QNetworkAccessManager accessManager;
    QNetworkRequest request;
    QUrl url("http://jiffyplace.com/photo.php?a=1&b=2");
    request.setUrl(url);
    request.setRawHeader("Host", "jiffyplace.com");
    request.setRawHeader("Cache-Control", "no-cache");
    request.setRawHeader("Accept","*/*");

    params.append("a=ok");
    params.append("b=ok2");

    reply = accessManager.post(request, "a=asd");

Ну это я тут уже разные варианты добавления параметров пробовал. Как-то через раз запрос отправляется. Вообще не пойму че за хрень...
Как все происходит... Отправляю запрос без параметров - ОК. Отправляю с параметрами - нифига. Снова без параметров - нифига, больше не отправляется. Вешал слот на сигнал готовности от reply - молчит. Помогайте, братцы!
Записан
Whiplash
Гость
« Ответ #1 : Сентябрь 07, 2011, 08:48 »

Ну, во-первых ты АкцессМенеджер на стеке создаёшь. После выхода из метода, в котором он создан, он у тебя умирает. Хороший АкцессМенеджер - живой АкцессМенеджер. Во-вторых, я бы всё-таки установил длину тела запроса
Код:
request.setHeader(QNetworkRequest::ContentLengthHeader, parmas.length());
Записан
Whiplash
Гость
« Ответ #2 : Сентябрь 07, 2011, 08:50 »

Вот, кстати, рабочий код. Это реализация методов класса Request. Если надо, запощу и хидер.
Код:
Request::Request(bool syn, QObject *parent) :
    QObject(parent),
    synhro(syn)
{
    manager=new QNetworkAccessManager(this);
    QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(sent(QNetworkReply*)));
}

void Request::setParametersForRequetsSlot(const QByteArray &method, const QByteArray &addr, QList<QByteArray> &headers, const QByteArray &body)
{
    p_method=method;
    p_addr=addr;
    p_headers=headers;
    p_body=body;
}

void Request::sendRequest()
{
    sendRequest(p_method, p_addr, p_headers, p_body);
}

void Request::sendRequest(const QByteArray &method, const QByteArray &addr, QList<QByteArray> &headers, const QByteArray &body)
{
    int type=0;
    QByteArray ba=method.simplified().toLower();
    if(ba.contains("put"))type=1;
    else if(ba.contains("get"))type=2;
    //post - default

    QNetworkRequest request;
    for(int i=0;i<headers.count();i++){
        ba=headers.at(i);
        int x=ba.indexOf(": ");
        if(x<0)continue;//игнорирование неверной строчки
        if(x==ba.length()-2)continue;
        request.setRawHeader(ba.left(x),ba.right(ba.length()-x-2));
    }
    if(type!=2) request.setHeader(QNetworkRequest::ContentLengthHeader, body.length()); //не гет
    request.setUrl(QUrl(addr));

    replyBody.clear();
    replyHeaders.clear();
    ended=false;

    switch(type){
    case 0: manager->post(request,body);
        break;
    case 1: manager->put(request, body);
        break;
    case 2: manager->get(request);
    }

    //подождать
    if(synhro) while(!ended)QCoreApplication::processEvents();
}

void Request::sent(QNetworkReply *reply)
{
    replyBody=reply->readAll();
    replyHeaders=reply->rawHeaderList();
    for(int i=0;i<replyHeaders.count();i++){
        replyHeaders[i]=replyHeaders.at(i)+": "+reply->rawHeader(replyHeaders.at(i));
    }
    replyError=reply->error();
    replyErrorString=reply->errorString();
    replyURL=reply->url().toString();
    ended=true;
    emit finished();
}
Записан
secatorr
Гость
« Ответ #3 : Сентябрь 07, 2011, 10:45 »

Да, думаю и хидеры пригодятся. Спасибо, буду пробовать. Моя ошибка, выходит, только в том, что в стеке АксессМенеджер создаю и не указываю длину?
А никто не работал с этими же запросами + Mobility. Мне вообще нужно с мобильного посылать? Там я так понимаю нужно сессию создавать. Просто создать и можно работать? Она как бы дает доступ к интернету для всего приложения?
Записан
Whiplash
Гость
« Ответ #4 : Сентябрь 07, 2011, 11:25 »

Про мобильность я ничем не помогу - кодю исключительно под десктоп.
Вот хидер
Код:
#ifndef REQUEST_H
#define REQUEST_H

#include <QObject>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkReply>

class Request : public QObject
{
    Q_OBJECT
public:
    explicit Request(bool syn=true, QObject *parent = 0);
    void sendRequest(const QByteArray &method, const QByteArray &addr, QList <QByteArray> &headers, const QByteArray &body);
    void setParametersForRequetsSlot(const QByteArray &method, const QByteArray &addr, QList <QByteArray> &headers, const QByteArray &body);
    const QByteArray& getReply(){
        return replyBody;
    }

    QList<QByteArray> getReplyHeaders(){
        return replyHeaders;
    }

    int getError(){
        return replyError;
    }

    QString getErrorString(){
        return replyErrorString;
    }

    QString getReplyURL(){
        return replyURL;
    }

    void synchronous(bool s=true){
        synhro=s;
    }

private:
    QNetworkAccessManager *manager;
    QByteArray replyBody;
    QList<QByteArray> replyHeaders;
    bool ended;
    int replyError;
    QString replyErrorString;
    QString replyURL;
    bool synhro;

    QByteArray p_method;
    QByteArray p_addr;
    QList <QByteArray> p_headers;
    QByteArray p_body;

public slots:
    void sendRequest();

private slots:
    void sent(QNetworkReply *reply);

signals:
    void finished();

};

#endif // REQUEST_H
Записан
Whiplash
Гость
« Ответ #5 : Сентябрь 07, 2011, 11:27 »

Щас ещё подумал... Ты в теле запроса передаёшь набор ключ-значение. А почему бы не передавать это всё в заголовке? А тело пусть пустое будет.
Записан
secatorr
Гость
« Ответ #6 : Сентябрь 07, 2011, 12:10 »

Спасибо. А есть разница? А как в заголовках передавать? Просто setRawHeader(имя, значение)?
Записан
Whiplash
Гость
« Ответ #7 : Сентябрь 07, 2011, 12:20 »

Спасибо. А есть разница? А как в заголовках передавать? Просто setRawHeader(имя, значение)?

Ну да, это и имел в виду. Просто посоветовал попробовать, вдруг так удобнее будет.
Записан
secatorr
Гость
« Ответ #8 : Сентябрь 07, 2011, 12:24 »

Спасибо за помощь. Буду пробовать.
Записан
secatorr
Гость
« Ответ #9 : Сентябрь 08, 2011, 00:52 »

Кто может дать советы по работе с сетью на Symbian с Mobility, буду очень рад!
Записан
secatorr
Гость
« Ответ #10 : Сентябрь 08, 2011, 02:26 »

А вот такой вопрос. Одновременно с параметрами пост-запроса хочу отправлять файл. Но! Файл отправляется, а пост-параметры нет)
Вот параметры запроса:
Код:
params.append("--AyV04a\r\n");
    params.append("content-disposition: ");
    params.append("form-data; name=\"p1\"\r\n");
    params.append("\r\n");
    params.append("Konstantin");
    params.append("\r\n");

    params.append("--AyV04a\r\n");
    params.append("content-disposition: ");
    params.append("file; name=\"file\"; filename=\""+file.fileName()+"\"\r\n");
    params.append("Content-Transfer-Encoding: binary\r\n");
    params.append("\r\n");
    params.append(file.readAll());
    params.append("\r\n");
    params.append("--AyV04a--");
    request.setHeader(QNetworkRequest::ContentLengthHeader, params.length());
Записан
secatorr
Гость
« Ответ #11 : Сентябрь 08, 2011, 02:29 »

Решено.
Перед
Код:
params.append("--AyV04a\r\n");
    params.append("content-disposition: ");
    params.append("form-data; name=\"p1\"\r\n");
    params.append("\r\n");
    params.appe...
было вставлено
Код:
params = "a=1&b=2";

Видать с этим проблема... Убрал и завелось! Иии-ха!
Записан
meandnano
Гость
« Ответ #12 : Сентябрь 14, 2011, 13:16 »

Спасибо. А есть разница? А как в заголовках передавать? Просто setRawHeader(имя, значение)?

Можешь спокойно использовать обычный QNetworkAcessManager без дополнительных танцев. Танцы пригодятся, если, например, будешь делать подключение через определенные точки доступа. А так - при запросе прога будет пытаться подключаться либо через дефолтную точку доступа, либо через открытую wlan сеть, либо предоставит выбор точки, через которую соединятся. Зависит от платформы и настроек.
У меня несколько приложений (на Symbian^3, Symbian 5th edition и Meego 1.2 Harmattan) работают через wifi/3G и все держится на стандартных настройках, post и get работают как на десктопе, при необходимости подключение к сети происходит автоматически.
Записан
NordWest
Гость
« Ответ #13 : Декабрь 15, 2011, 13:44 »

Цитировать
Код:
params.append("--AyV04a\r\n");
Скажите, а что значат эти строки? Это значение откуда берется. Похоже что-то типа кода сессии, его получить где-то надо?
Записан
thechicho
Гость
« Ответ #14 : Январь 01, 2012, 19:52 »

http://ru.wikipedia.org/wiki/HTTP#POST
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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