2

Delphi で HTML で送信した投稿値を取得したい。を使用してTIdHTTPServerいます。

私の目標は、POST で送信されたデータを取得することです。しかし問題がある。下の写真のようなツールで「form-data」として送信します。POST リクエストのキャプチャ。

画像

残念ながら、 HTMLと同じリクエストを行うと、POST が表示されません。どうすればこれを達成できますか?

procedure TForm1.serviceCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  receiveStream: TStream;
begin
  if ARequestInfo.URI = '/test.php' then
  begin
    if ARequestInfo.Command = 'POST' then
    begin
      receiveStream := ARequestInfo.PostStream;
      if Assigned(receiveStream) then
      begin
        LOG.Lines.Add(ReadStringFromStream(receiveStream));
      end;
      AResponseInfo.ResponseNo := 200;
    end;
  end;
end;

HTML POST リクエスト (Delphi はそのリクエストを認識しません。私の目標は、その願いを叶えることです。)

<form method="post" action="http://localhost:99/test.php"> 
    <input type="hidden" name="test" value="04545">
    <input type="submit" value="send"/>
</form>
4

1 に答える 1

5

まず、次のように言うことから始めましょう。

  • if ARequestInfo.Command = 'POST' thenどちらかに変更する必要があります

    if TextIsSame(ARequestInfo.Command, 'POST') then

    またはそれ以上

    if ARequestInfo.CommandType = hcPOST then

  • OnCommand...イベント ハンドラーはワーカー スレッドのコンテキストで起動されるため、UI へのすべてのアクセスはメインの UI スレッドと同期する必要があります。

application/x-www-webform-urlencoded次に、表示された HTML は、メディア タイプを使用して Web フォームの値を HTTP サーバーに送信します。TIdHTTPServer.OnCommandGetイベントでは、ARequestInfo.PostStreamプロパティはそのメディア タイプでは使用されず、 になりますnil。投稿された Web フォームの値は、代わりにおよびプロパティで元の解析されていない形式で利用でき、プロパティが True (デフォルト)の場合はプロパティで解析された形式で利用できます。ARequestInfo.FormParamsARequestInfo.UnparsedParamsARequestInfo.ParamsTIdHTTPServer.ParseParams

代わりにこれを試してください:

procedure TForm1.serviceCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  testValue: string;
begin
  if ARequestInfo.URI <> '/test.php' then
  begin
    AResponseInfo.ResponseNo := 404;
    Exit;
  end;
  if ARequestInfo.CommandType <> hcPOST then
  begin
    AResponseInfo.ResponseNo := 405;
    Exit;
  end;
  testValue := ARequestInfo.Params.Values['test'];
  TThread.Queue(nil,
    procedure
    begin
      LOG.Lines.Add('test: ' + testValue);
    end
  );
  AResponseInfo.ResponseNo := 200;
end;

multipart/form-dataそうは言っても、テストツールの「フォームデータ」はメディアタイプを指します。HTML で、そのメディア タイプを使用して Web フォームを投稿する場合は、要素のenctypeパラメーターで明示的に指定する必要があります。たとえば、次のようになります。<form>

<form method="post" action="http://localhost:99/test.php" enctype="multipart/form-data"> 
    <input type="hidden" name="test" value="04545">
    <input type="submit" value="send"/>
</form>

その場合、は現在投稿のTIdHTTPServer解析をサポートしていないmultipart/form-dataため、サポートされARequestInfo.PostStreamませんnil。必要に応じてデータを手動で解析できるように、Web フォームの未加工のバイトを提供します。

ARequestInfo.ContentTypeプロパティを確認することで、Web フォームの投稿に使用されるメディア タイプを区別できます。

procedure TForm1.serviceCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  testValue: string;
  data: string;
begin
  if ARequestInfo.URI <> '/test.php' then
  begin
    AResponseInfo.ResponseNo := 404;
    Exit;
  end;
  if ARequestInfo.CommandType <> hcPOST then
  begin
    AResponseInfo.ResponseNo := 405;
    Exit;
  end;
  if IsHeaderMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
  begin
    testValue := ARequestInfo.Params.Values['test'];
    TThread.Queue(nil,
      procedure
      begin
        LOG.Lines.Add('test: ' + testValue);
      end
    );
    AResponseInfo.ResponseNo := 200;
  end
  else if IsHeaderMediaType(ARequestInfo.ContentType, 'multipart/form-data') then
  begin
    data := ReadStringFromStream(ARequestInfo.PostStream);
    TThread.Queue(nil,
      procedure
      begin
        LOG.Lines.Add('form-data: ' + data);
      end
    );
    AResponseInfo.ResponseNo := 200;
  end else
  begin
    AResponseInfo.ResponseNo := 415;
  end;
end;
于 2020-06-25T17:24:42.000 に答える