Qtでマルチパート/フォームデータリクエストを送信する

ネットワークアプリケーションを開発するときに、サーバーにファイルをアップロードするというタスクが発生することがあります。これは、そのようにではなく、完成したhttpフォームの一部としてです。 これは、いわゆるmultipart / form-dataリクエストの例です。 Qtライブラリの標準メソッドではこれが許可されていないため、自分で脱出する必要があります。



一般的な情報



それでは、まず、マルチパート/フォームデータリクエストの興味深いところを理解する必要がありますか?

ここから例を見ると、一般的なクエリは次のとおりです。



 POST http://www.site.ru/news.html HTTP / 1.0 \ r \ n
ホスト:www.site.ru \ r \ n
リファラー:http://www.site.ru/index.html\r\n
 Cookie:収入= 1 \ r \ n
コンテンツタイプ:multipart / form-data; 境界= 1BEF0A57BE110FD467A \ r \ n
コンテンツの長さ:209 \ r \ n
 \ r \ n
 --1BEF0A57BE110FD467A \ r \ n
コンテンツの処理:フォームデータ。  name = "login" \ r \ n
 \ r \ n
ペティアヴァセチキン\ r \ n
 --1BEF0A57BE110FD467A \ r \ n
コンテンツの処理:フォームデータ。  name = "password" \ r \ n
 \ r \ n
 qq \ r \ n
 --1BEF0A57BE110FD467A-\ r \ n


ヘッダーに特に関心があるのは、 境界= 1BEF0A57BE110FD467AおよびContent-Length:209であり 、その後に要求本文が始まります。 リクエストはいくつかの部分で構成されますが、セパレータは境界として書き込まれるものと見なされますが、リクエストの本文の長さも示す必要があります-これはContent-Lengthフィールドです。 リクエスト本文は、最初の行--1BEF0A57BE110FD467Aから始まるすべてです 。 各セクションで、nameは対応するフォームフィールドの名前です。2つの改行の後、\ r \ n \ r \ nフィールドの値



ファイルを送信するには、次の形式のセクションを作成する必要があります。



 --1BEF0A57BE110FD467A \ r \ n
コンテンツの処理:フォームデータ。  name = "news_file";  filename = "news.txt" \ r \ n
コンテンツタイプ:アプリケーション/オクテットストリーム\ r \ n
 Content-Transfer-Encoding:バイナリ\ r \ n
 \ r \ n
そして、これはファイルnews.txtにあるニュースです\ r \ n


ここでは、ファイル名が追加で指定されます-news.txt、およびContent-Transfer-Encodingフィールドのデータエンコーディング。 バイナリー表現(エンコードされていないデータ)を含む、いくつかの異なるエンコードがあります。 Qtの機能を考えると、base64エンコーディングを使用するのは非常に便利です。 ファイルがそこ(application / octet-stream)だけでなく、既知のタイプである場合、Content-Typeフィールドでこのタイプを指定できます(例:Content-Type:image / png)



簡単な例



クエリ生成の実用的な例に移りましょう。 私たちが持っています:



// ++   Qt QNetworkAccessManager *manager; // 1 - - ,  2 -  QByteArray param1Name="param1" ,param1Value="value1"; QByteArray param2Name="param2", param2FileName="news.txt", param2ContentType="text/plain",param2Data="   ,     news.txt";
      
      





まず、リクエストの本文を作成します。



 //  QByteArray postData,boundary="1BEF0A57BE110FD467A"; //  postData.append("--"+boundary+"\r\n");// //  postData.append("Content-Disposition: form-data; name=\""); postData.append(param1Name); postData.append("\"\r\n\r\n"); //  postData.append(param1Value); postData.append("\r\n"); // 2 -  postData.append("--"+boundary+"\r\n");// //  postData.append("Content-Disposition: form-data; name=\""); postData.append(param2Name); //  postData.append("\"; filename=\""); postData.append(param2FileName); postData.append("\"\r\n"); //   postData.append("Content-Type: "+param2ContentType+"\r\n"); //  base64 postData.append("Content-Transfer-Encoding: base64\r\n\r\n"); // postData.append(param2Data.toBase64()); postData.append("\r\n"); //""  postData.append("--"+boundary+"--\r\n");
      
      





postData変数では、完成したリクエストボディを取得します。送信するだけであり、追加のリクエストヘッダーを設定することを忘れないでください。



 QNetworkRequest request(QUrl("http://example.com/submit.php")); request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary="+boundary); request.setHeader(QNetworkRequest::ContentLengthHeader, QByteArray::number(postData.length())); QNetworkReply *reply=manager->post(request,postData);
      
      





さて、それでは-他のリクエストと同様に、親指で追跡します。



最後に...



上記の例は、もちろん、日常的に使用するには単純すぎます。 しかし、その基礎に基づいて、生成するクエリの複雑さに応じて、特定のタスクごとに関数、クラス、またはクラスライブラリを簡単に実装できます。



有用な情報:

http://www.codenet.ru/webmast/php/HTTP-POST.php-HTTPリクエストの入力の説明。

http://www.ietf.org/rfc/rfc2388.txt-標準「フォームからの戻り値:multipart / form-data」



All Articles