2010-04-08 10 views
46

J'ai un service Web dont j'ai besoin pour POST certaines données à l'aide de Qt. J'ai pensé que je peux utiliser un QByteArray lors de la POST au service Web.Comment puis-je envoyer des données à une URL à l'aide de QNetworkAccessManager

Ma question est, comment puis-je formater ce tableau afin d'être analysé correctement à l'autre bout?

C'est le code que j'ai jusqu'à présent:

// Setup the webservice url 
    QUrl serviceUrl = QUrl("http://myserver/myservice.asmx"); 
    QByteArray postData; 

    /* 
    Setup the post data somehow 
    I want to transmit: 
    param1=string, 
    param2=string 
    */ 

    // Call the webservice 
    QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); 
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); 
    networkManager->post(QNetworkRequest(serviceUrl), postData); 

Merci!

Répondre

14

J'utilisé:

QByteArray postData; 
postData.append("param1=string&"); 
postData.append("param2=string"); 

Alors & au lieu de chaque paramètre après saut de ligne.

+7

Cette approche ne protège pas contre les caractères & dans l'entrée. Si 'chaîne' est une entrée utilisateur, ils peuvent injecter des paramètres. – Halfgaar

-4
QByteArray postData; 
postData.append("param1=string,\n"); 
postData.append("param2=string\n"); 
+2

Cela ne fonctionne même pas – relipse

5

le fait répondre est

QByteArray postData; 
postData.append("param1=string&"); 
postData.append("param2=string"); 

REMARQUE: utiliser "&" ici !!!.

Je n'ai pas remarqué la réponse de Juha ici, et perdre beaucoup de temps à tester mon code en utilisant l'approche ", \ n".

Veuillez changer la bonne réponse pour Juha.

101

Étant donné que certains paramètres et les valeurs pourraient avoir besoin d'être utf-8 et pour cent codées (espaces, &, =, caractères spéciaux ...), vous devriez plutôt utiliser QUrl (pour Qt 4) ou QUrlQuery (pour Qt 5) pour construire la chaîne affichée.

Exemple de code pour Qt 4:

QUrl postData; 
postData.addQueryItem("param1", "string"); 
postData.addQueryItem("param2", "string"); 
... 
QNetworkRequest request(serviceUrl);  
request.setHeader(QNetworkRequest::ContentTypeHeader, 
    "application/x-www-form-urlencoded"); 
networkManager->post(request, postData.encodedQuery()); 

et Qt 5:

QUrlQuery postData; 
postData.addQueryItem("param1", "string"); 
postData.addQueryItem("param2", "string"); 
... 
QNetworkRequest request(serviceUrl); 
request.setHeader(QNetworkRequest::ContentTypeHeader, 
    "application/x-www-form-urlencoded"); 
networkManager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8()); 

A partir de Qt 4.8, vous pouvez également utiliser QHttpMultiPart si vous avez besoin de télécharger des fichiers.

+7

Ceci est certainement le moyen le plus approprié d'accomplir la tâche en question. +1 –

+2

À partir de Qt 5, QUrl n'a plus addQueryItem(). – mjk99

+1

@ mjk99 'QUrlQuery' fait, mais il n'a pas' .encodedQuery() ' – JVE999

2

Voici une autre façon de gérer cela, je suis en utilisant votre code aussi pour donner un code complet:

 // Setup the webservice url   
    QUrl serviceUrl = QUrl("http://myserver/myservice.asmx"); 
    QByteArray postData; 

    QUrl params; 
    params.addQueryItem("param1","string1"); 
    params.addQueryItem("param2","string2"); 

    postData = params.encodedQuery(); 

    // Call the webservice 
    QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); 
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); 

     networkManager->post(QNetworkRequest(serviceUrl), postData); 
7

Mise à jour alexisdm réponse à QT5:

// Setup the webservice url 
QUrl serviceUrl = QUrl("http://your.url"); 
QByteArray postData; 

QUrl params; 
QUrlQuery query; 
query.addQueryItem("param1","string1"); 
query.addQueryItem("param2","string2"); 

params.setQuery(query); 

postData = params.toEncoded(QUrl::RemoveFragment); 

// Call the webservice 
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this); 
connect(networkManager, SIGNAL(finished(QNetworkReply*)), 
     SLOT(onPostAnswer(QNetworkReply*))); 

QNetworkRequest networkRequest(serviceUrl); 
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded"); 

networkManager->post(networkRequest,postData); 

Ne pas oublier d'inclure

QT += network 

dans .pro.

+1

Ce que fait ce code différemment que de construire un QByteArray comme Juha, c'est que le postData est '"? Param1 = string1 & param2 = string2 "', ce qui ne va pas. – Halfgaar

+1

Si vous faites plusieurs requêtes en utilisant le même gestionnaire d'accès réseau, il est logique de connecter l'emplacement au signal 'finished()' de 'QNetworkReply' au lieu de' QNetworkAccessManager'. De cette façon, vous pouvez avoir différents signaux par requête et les gérer séparément, ou gérer les données partie par partie en utilisant le signal 'readyRead()'. – nurettin