2010-12-22 11 views
6

Ho provato tutto il giorno senza successo. Si prega di aiutare a risolvere il problema. Su googlando ho trovato che molti utenti avevano questo problema ma da nessuna parte ho potuto trovare una soluzione.QT Messaggio HTTP Post quando il server richiede i cookie

che sto cercando di fare posta HTTP in QT C++ & Ho già provato a farlo in python (La mia domanda non è una domanda di pitone, in modo pro Qt per favore aiutatemi) .. lo so, io sono da qualche parte sbagliata in gestione dei cookie e tutto, quindi per favore aiutatemi. Si prega di fornire soluzioni probabili.

In python, il codice è pulito e semplice. Ho eliminato la gestione degli errori e tutte le cose extra per renderlo semplice.

url = 'http://www.example.com/' 
data = 'username=abc&password=passwd' 
cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
usock = opener.open(url, data) 
#>>>>>> NOW, I have the cookiejar <<<<<<<<< 

opener.addheaders = [('Referer','http://www.example.com/xyz.php'),('User-Agent','Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3 GTB7.0')] 
data_to_send = 'ABCDEFGH' 
url_send = "http://www.example.com/xyz.php" 
send = opener.open(url_send,data_to_send) 

l'equivalente QT ho fatto: -

void SmsSender::sendToMyCantos() 
{ 
    manager = new QNetworkAccessManager(this); 
    manager->setCookieJar(new QNetworkCookieJar(manager)); 
    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); 
    request.setUrl(QUrl("http://www.mycantos.com")); 
    postData.append("username=abc&password=passwd"); 
    manager->post(request,postData); 
    //>>>>>> So, I feel that I have CookieJar now to make POST <<<<<<< 

    request.setRawHeader("Referer","http://www.example.com/xyz.php"); 
    request.setRawHeader("User-Agent","Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3 GTB7.0"); 

    postData.clear(); 
    postData.append("ABCDEFGH"); 
    request.setUrl(QUrl("http://www.example.com/xyz.php")); 

    manager->post(request,postData); 
} 

Ora il problema è che io non sono in grado di fare lo stesso in QT. I problemi che sto affrontando:

  1. gestione dei cookie
  2. Handling redirect (HTTP 302)
  3. ritegno i cookie per rendere il futuro POST

Tutto questo viene fatto automagicamente in pitone. Sotto, il codice non è direttamente correlata, ma ho codificato questo per consentire reindirizzamenti nel post .. Il codice è very similar to the link I used to make it..

QUrl SmsSender::redirectUrl(const QUrl& possibleRedirectUrl, 
           const QUrl& oldRedirectUrl) const { 
     //Checking infinite resursions 
     QUrl redirectUrl; 
     if(!possibleRedirectUrl.isEmpty() && 
      possibleRedirectUrl != oldRedirectUrl) { 
       redirectUrl = possibleRedirectUrl; 
     } 
     return redirectUrl; 
} 

void SmsSender::replyFinished(QNetworkReply *reply) 
{ 
    QVariant possibleRedirectUrl = 
      reply->attribute(QNetworkRequest::RedirectionTargetAttribute); 
    QVariant data_size = reply->header(QNetworkRequest::ContentLengthHeader); 
    qDebug()<<data_size.toFloat(); 
    qDebug()<<manager->cookieJar()->cookiesForUrl(QUrl("http://www.example.com")); 

    /* We'll deduct if the redirection is valid in the redirectUrl function */ 
    _urlRedirectedTo = this->redirectUrl(possibleRedirectUrl.toUrl(), 
             _urlRedirectedTo); 

    /* If the URL is not empty, we're being redirected. */ 
    if(!_urlRedirectedTo.isEmpty()) { 
      QString text = QString("SmsSender::replyFinished: Redirected to ") 
            .append(_urlRedirectedTo.toString()); 
    qDebug(text.toAscii()); 

    // Do again in case we have more redirections 

    this->_qnam->get(QNetworkRequest(_urlRedirectedTo)); 
    } 
    else 
    { 
     QString text = QString("SmsSender::replyFinished: Arrived to ") 
            .append(reply->url().toString()); 
     qDebug(text.toAscii()); 
     _urlRedirectedTo.clear(); 
    } 

} 

QNetworkAccessManager* SmsSender::createQNAM() { 
     QNetworkAccessManager* qnam = new QNetworkAccessManager(this); 
     /* We'll handle the finished reply in replyFinished */ 
     connect(qnam, SIGNAL(finished(QNetworkReply*)), 
       this, SLOT(replyFinished(QNetworkReply*))); 
     return qnam; 
} 
+0

Questo è il mio primo tentativo di utilizzare QT per creare un'app, quindi per favore portatemi se non è corretto come per gli standard. –

risposta

7

Io lo uso per ottenere un biscotto:

SomeDialog::SomeDialog(QWidget *parent) 
    : QDialog(parent) 
     , urlSearch("www.someotherurlyoumightneed.com") 
    , urlCookie("www.urltogetcookie.from") 
{ 
    ui.setupUi(this); 

    //manager is a QNetworkAccessManager 
    manager.setCookieJar(new QNetworkCookieJar); 
    connect(&manager, SIGNAL(finished(QNetworkReply*)), 
     SLOT(slotReplyFinished(QNetworkReply*))); 

    //this is a QNetworkRequest 
    //here i tell how the post methods are encoded 
    searchReq.setUrl(urlSearch); 
    searchReq.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded"); 

    //get cookie 
    manager.get(QNetworkRequest(urlCookie)); 
    lblStatus->setText("Getting cookie"); 
} 

void SomeDialog::slotReplyFinished(QNetworkReply* reply){ 
    reply->deleteLater(); 

    if(reply->error() != QNetworkReply::NoError){ 
     QMessageBox::warning(this,QString(), tr("Error while downloading information!\n%1").arg(reply->errorString())); 

     return; 
    } 

    //Here i check if there is a cookie for me in the reply and extract it 
    QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader)); 
    if(cookies.count() != 0){ 
     //you must tell which cookie goes with which url 
     manager.cookieJar()->setCookiesFromUrl(cookies, urlSearch); 
    } 

    //here you can check for the 302 or whatever other header i need 
    QVariant newLoc = reply->header(QNetworkRequest::LocationHeader); 
    if(newLoc.isValid()){ 
     //if it IS a reloc header, get the url it points to 
     QUrl url(newLoc.toString()); 
     _req.setUrl(url); 
     _pendingReq.insert(_manager.get(_req)); 
     return; 
    } 

    //if you have multiple urls you are waiting for replys 
    //you can check which one this one belongs to with 
    if(reply->url() == urlSearch){ 
     //do something 
    } 
} 

void SomeDialog::slotSearch(){ 
    //Here we set the data needed for a post request 
    QList<QNetworkCookie> cookies = manager.cookieJar()->cookiesForUrl(urlSearch); 
    for(auto it = cookies.begin(); it != cookies.end(); ++it){ 
     searchReq.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(*it)); 
    } 

    QUrl post; 
    post.addQueryItem("firstParameter", s); 
    post.addQueryItem("secondParameter", "O"); 
    QByteArray ba; 
    ba.remove(0,1); //must remove last & 

    searchReq.setUrl(urlSearch); 
    pendingReq.insert(manager.post(searchReq, ba)); 
} 

Spero che questo aiuti.

0

Credo che i cookie sono legate agli URL sono ottenuti da. Quindi nel tuo secondo POST con un URL diverso, i cookie del primo POST non vengono inviati con la richiesta.

Problemi correlati