TNetHTTPClientを使ってWebサーバーにGET、Postを行う ~Delphiでお手軽プログラミング

TNetHTTPClientを使ってWebサーバーにGET、Postを行う ~Delphiでお手軽プログラミング

TNetHTTPClientを使うとGET・Postでパラメータを与えることも、カスタムヘッダーやCookieを扱うこともできます。

フォーム画面の作成

Delphi IDEを起動し、「ファイル」⇒「Windows VCLアプリケーション -Delphi」をクリックします
フォームにTButtonを2つ、TNetHTTPClientを1つ、TMemoを1つをドラッグ&ドロップします。

プログラムの作成

以下ソースコードを記述します。
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Net.URLClient,
  System.Net.HttpClient, System.Net.HttpClientComponent;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    NetHTTPClient1: TNetHTTPClient;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure NetHTTPClient1AuthEvent(const Sender: TObject;
      AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,
      APassword: string; var AbortAuth: Boolean;
      var Persistence: TAuthPersistenceType);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;


  //クラスヘルパーでクッキーを消せるようにする
  TCookieManagerHelper = class helper for TCookieManager
    procedure DeleteCookie(i:Integer);
    procedure DeleteAllCookies();
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
uses System.NetEncoding;

{TCookieManagerHelper}
procedure TCookieManagerHelper.DeleteCookie(i:Integer);
begin  //i番目のクッキーを消す
  with self do
    FCookies.Delete(i);
end;
procedure TCookieManagerHelper.DeleteAllCookies();
begin  //全てのクッキーを消す
  with self do
    FCookies.Clear;
end;

{TForm1}

procedure TForm1.Button1Click(Sender: TObject);
var strm:TMemoryStream; //サーバーからの応答コンテンツの格納用ストリーム
    res:IHTTPResponse;  //サーバーからの応答
    Header:TNetHeaders; //カスタムヘッダー生成用
    i:Integer;
    Cookie:TCookie;     //クッキー生成用
    AUrl:TURI;
    b:TBytes;
    GerParam:string;    //GETパラメータ生成用
begin
  strm:=TMemoryStream.Create;
  try
    //ユーザーエージェントを適当に設定
    NetHTTPClient1.UserAgent:=
      'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) '+
      'AppleWebKit/605.1.15 (KHTML, like Gecko) '+
      'Version/12.0 Mobile/15E148 Safari/604.1';

    //クッキーを受け取れるようにする
    NetHTTPClient1.AllowCookies:=True;

    //クッキーを設定する
    NetHTTPClient1.CookieManager.AddServerCookie(
      'cookie1=cookieValue1',
      'http://localhost'
    );
    //クッキーを設定する
    NetHTTPClient1.CookieManager.AddServerCookie(
      'cookie2=cookieValue2',
      'http://localhost'
    );

    //クッキーを設定する
    Cookie.Name:='cookie3';
    b:=TEncoding.UTF8.GetBytes('UTF8の日本語をクッキーに入れてみる');
    Cookie.Value:=System.NetEncoding.TURLEncoding.URL.EncodeBytesToString(b);
    Cookie.Expires:=EncodeDate(2025,1,1);//有効期限
    Cookie.Domain:='.localhost';          //ドメイン
    Cookie.Path:='/';
    Cookie.Secure:=False;                //セキュアフラグ
    Cookie.HttpOnly:=True;               //HTTPOnlyフラグ
    AUrl.Create('http://localhost');
    NetHTTPClient1.CookieManager.AddServerCookie(Cookie,AUrl);

    //カスタムヘッダーを設定する
    //  基本(ベーシック)認証のヘッダーを生成する
    SetLength(Header,1);
    Header[0].Create(
      'Authorization',
      'Basic '+TNetEncoding.Base64.Encode('user:password')
    );

    //GETパラメータを設定する
    b:=TEncoding.UTF8.GetBytes('UTF8の日本語をGETで生成する');
    GerParam:='getname='+
      System.NetEncoding.TURLEncoding.URL.EncodeBytesToString(b);

    //WebサーバーにGET接続する
    res:=NetHTTPClient1.Get(
      'http://localhost/tnethttpclient_test.php?'+GerParam,
      strm,Header
    );

    //届いたコンテンツをUTF8文字として出力する
    memo1.Lines.LoadFromStream(strm,TENcoding.UTF8);
    memo1.Lines.Insert(0,'■届いたコンテンツ');
    memo1.Lines.Add('--------------------------------');

    //charsetを出力する(届かないサーバーもある)
    memo1.Lines.Insert(0,'■届いたコンテンツの文字コード');
    memo1.Lines.Insert(1,res.ContentCharSet);
    memo1.Lines.Insert(2,'--------------------------------');

    //サーバー側で設定(追加、変更)されたクッキーを出力する
    memo1.Lines.Add('■サーバー側で設定(追加、変更)されたクッキー');
    for i := 0 to res.Cookies.Count-1 do
    begin
      memo1.Lines.Add(
        res.Cookies[i].Name+' : '+
        System.NetEncoding.TURLEncoding.URL.Decode(res.Cookies[i].Value)
      );
    end;
    memo1.Lines.Add('--------------------------------');

    //現在の全てのクッキーを出力する
    memo1.Lines.Add('■現在のクッキー');
    for i := 0 to Length(NetHTTPClient1.CookieManager.Cookies)-1 do
    begin
      memo1.Lines.Add(
        '('+
        NetHTTPClient1.CookieManager.Cookies[i].Domain+
        NetHTTPClient1.CookieManager.Cookies[i].Path+
        ') '+
        NetHTTPClient1.CookieManager.Cookies[i].Name+': '+
        System.NetEncoding.TURLEncoding.URL.Decode(
          NetHTTPClient1.CookieManager.Cookies[i].Value
        )
      );
    end;
    memo1.Lines.Add('--------------------------------');

    //届いたヘッダーを出力する
    memo1.Lines.Add('■届いたヘッダー');
    for i := 0 to length(res.Headers)-1 do
    begin
      memo1.Lines.Add(
        res.Headers[i].Name+':'+res.Headers[i].Value
      );
    end;

  finally
    strm.Free;
  end;

  //0個目のクッキーを消す
  //NetHTTPClient1.CookieManager.DeleteCookie(0);

  //全てのクッキーを消す
  NetHTTPClient1.CookieManager.DeleteAllCookies;
end;



procedure TForm1.Button2Click(Sender: TObject);
var stl:TStringList;    //Postの値を入れる
    strm:TMemoryStream; //サーバーからの応答コンテンツが入る
    res:IHTTPResponse;  //サーバーからの応答
    i:Integer;
begin
  //POSTする場合
  Memo1.Clear;
  stl:=TStringList.Create;
  strm:=TMemoryStream.Create;
  try
    stl.Add('postname1=値1');
    stl.Add('postname2=値2');

    //WebサーバーにPOST接続する
    res:=NetHTTPClient1.Post(
      'http://localhost/tnethttpclient_test.php',
      stl,            //Postする値
      strm,           //レスポンスストリーム
      TEncoding.UTF8, //Postする文字列の文字コード
      [] //カスタムヘッダ
    );

    //届いたコンテンツをUTF8文字として出力する
    memo1.Lines.LoadFromStream(strm,TENcoding.UTF8);
    memo1.Lines.Insert(0,'■届いたコンテンツ');
    memo1.Lines.Add('--------------------------------');

    //charsetを出力する
    memo1.Lines.Insert(0,'■届いたコンテンツの文字コード');
    memo1.Lines.Insert(1,'  '+res.ContentCharSet);
    memo1.Lines.Insert(2,'--------------------------------');

    //現在の全てのクッキーを出力する
    memo1.Lines.Add('■現在のクッキー');
    for i := 0 to Length(NetHTTPClient1.CookieManager.Cookies)-1 do
    begin
      memo1.Lines.Add(
        '('+
        NetHTTPClient1.CookieManager.Cookies[i].Domain+
        NetHTTPClient1.CookieManager.Cookies[i].Path+
        ') '+
        NetHTTPClient1.CookieManager.Cookies[i].Name+': '+
        System.NetEncoding.TURLEncoding.URL.Decode(
          NetHTTPClient1.CookieManager.Cookies[i].Value
        )
      );
    end;
    memo1.Lines.Add('--------------------------------');

    //届いたヘッダーを出力する
    memo1.Lines.Add('■届いたヘッダー');
    for i := 0 to length(res.Headers)-1 do
    begin
      memo1.Lines.Add(
        res.Headers[i].Name+':'+res.Headers[i].Value
      );
    end;

  finally
    stl.Free;
    strm.Free;
  end;

  //0個目のクッキーを消す
  //NetHTTPClient1.CookieManager.DeleteCookie(0);

  //全てのクッキーを消す
  NetHTTPClient1.CookieManager.DeleteAllCookies;
end;

procedure TForm1.NetHTTPClient1AuthEvent(const Sender: TObject;
  AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,
  APassword: string; var AbortAuth: Boolean;
  var Persistence: TAuthPersistenceType);
begin
  //基本認証はこのイベント(TNetHTTPClient.OnAuthEvent)でも認証可能
  if AnAuthTarget = TAuthTargetType.Server then
  begin
    AUserName:='user';
    APassword:='password';
  end;
end;

end.

(参考)WEBサーバー側(localhost)のPHPソースコード

<?php  //文字コードUTF-8で保存すること

//届いたクッキーの内容を出力する
if(count($_COOKIE)>0){
  echo "クッキーを受け取りました\r\n";
  foreach($_COOKIE as $key=>$val){
    echo '  '.$key.'='.$val."\r\n";
    //file_put_contents(__DIR__.'/tnethttpclient.txt',$val."\r\n",FILE_APPEND);
  }
}

//届いたGET又はPOSTの内容を出力する
if(count($_REQUEST)>0){
  echo "GET又はPOSTでパラメータを受け取りました\r\n";
  foreach($_REQUEST as $key=>$val){
    echo '  '.$key.'='.$val."\r\n";
    //file_put_contents(__DIR__.'/tnethttpclient.txt',$val."\r\n",FILE_APPEND);
  }
}

//届いた基本認証ヘッダーを出力
if(isset(getallheaders()['Authorization'])){
  echo "基本認証ヘッダーを受け取りました\r\n";
  echo "  Authorization: ".getallheaders()['Authorization']."\r\n";
}

//WEBサーバー側でクッキーを設定
setCookie('cookie3','Set Cookie3 Value from WebServer');
setCookie('cookie4','Set Cookie4 Value from WebServer');

実行してみる

実行して、Button1をクリックするとGETメソッドでサーバーに接続して応答などが表示されます。
Button2をクリックするとPOSTメソッドでサーバーに接続して応答などが表示されます。

(参考)GETで送信時のヘッダーと受信時のヘッダー

GETメソッドでサーバーに送信するHTTPヘッダー
以下の赤字の個所でクッキーを送信している
Connection: Keep-Alive
Authorization: Basic dXNlcjpwYXNzd29yZA==
Cookie: cookie3=UTF8%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%92%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E3%81%AB%E5%85%A5%E3%82%8C%E3%81%A6%E3%81%BF%E3%82%8B; cookie2=cookieValue2; cookie1=cookieValue1
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone ・・・省略
Host: 192.168.1.2
GETメソッドでサーバーから受信するHTTPヘッダー
以下の赤字の個所でクッキーを受信している
Date: Tue, 08 Mar 2022 10:33:16 GMT
Server: Apache/2.4.27 (Win64) OpenSSL/1.1.0f PHP/7.2.7
X-Powered-By: PHP/7.2.7
Set-Cookie: cookie3=Set+Cookie3+Value+from+WebServer
Set-Cookie: cookie4=Set+Cookie4+Value+from+WebServer
Content-Length: 287
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8