2

Delphi 使用: 2007.

こんにちは、

2 つのテキスト入力と 1 つのファイル入力を備えた単純な Web ページがあります。ここで、フォームを送信するには、テキスト入力とファイル入力の両方を入力する必要があります。Synapse では、ファイルをアップロードする方法 ( HttpPostFile ) とデータを投稿する方法 ( HttpMethod ) を知っています。しかし、私は両方を行う方法がわかりません。

Synapse のソース コードを見た後、データを境界などで "フォーマット" する必要があると思います。入力ファイル用に 1 つの境界を設定し、テキスト入力用に別の境界を設定する必要があると思います。この件に関する記事を見つけましたが、それは電子メールの添付ファイルの送信に関するものです。彼らが言ったことを Synapse で再現しようとしましたが、結果はありませんでした。

HttpPostFileのコード:

function HttpPostFile(const URL, FieldName, FileName: string;
  const Data: TStream; const ResultData: TStrings): Boolean;
var
  HTTP: THTTPSend;
  Bound, s: string;
begin
  Bound := IntToHex(Random(MaxInt), 8) + '_Synapse_boundary';
  HTTP := THTTPSend.Create;
  try
    s := '--' + Bound + CRLF;
    s := s + 'content-disposition: form-data; name="' + FieldName + '";';
    s := s + ' filename="' + FileName +'"' + CRLF;
    s := s + 'Content-Type: Application/octet-string' + CRLF + CRLF;
    WriteStrToStream(HTTP.Document, s);
    HTTP.Document.CopyFrom(Data, 0);
    s := CRLF + '--' + Bound + '--' + CRLF;
    WriteStrToStream(HTTP.Document, s);
    HTTP.MimeType := 'multipart/form-data; boundary=' + Bound;
    Result := HTTP.HTTPMethod('POST', URL);
    if Result then
      ResultData.LoadFromStream(HTTP.Document);
  finally
    HTTP.Free;
  end;
end;

ありがとうございました。

4

2 に答える 2

4

あなたのコードは近いです。ファイルフィールドのみを送信していますが、テキストフィールドは送信していません。3 つすべてを行うには、代わりにこれを試してください。

function HttpPostFile(const URL, InputText1FieldName, InputText1, InputText2FieldName, InputText2, InputFileFieldName, InputFileName: string; InputFileData: TStream; ResultData: TStrings): Boolean; 
var 
  HTTP: THTTPSend; 
  Bound: string; 
begin 
  Bound := IntToHex(Random(MaxInt), 8) + '_Synapse_boundary'; 
  HTTP := THTTPSend.Create; 
  try 
    WriteStrToStream(HTTP.Document,
      '--' + Bound + CRLF +
      'Content-Disposition: form-data; name=' + AnsiQuotedStr(InputText1FieldName, '"') + CRLF +
      'Content-Type: text/plain' + CRLF +
      CRLF); 
    WriteStrToStream(HTTP.Document, InputText1); 
    WriteStrToStream(HTTP.Document,
      CRLF +
      '--' + Bound + CRLF +
      'Content-Disposition: form-data; name=' + AnsiQuotedStr(InputText2FieldName, '"') + CRLF +
      'Content-Type: text/plain' + CRLF +
      CRLF); 
    WriteStrToStream(HTTP.Document, InputText2); 
    WriteStrToStream(HTTP.Document,
      CRLF +
      '--' + Bound + CRLF +
      'Content-Disposition: form-data; name=' + AnsiQuotedStr(InputFileFieldName, '"') + ';' + CRLF + 
      #9'filename=' + AnsiQuotedStr(InputFileName, '"') + CRLF +
      'Content-Type: application/octet-string' + CRLF +
      CRLF); 
    HTTP.Document.CopyFrom(InputFileData, 0); 
    WriteStrToStream(HTTP.Document,
      CRLF +
      '--' + Bound + '--' + CRLF); 
    HTTP.MimeType := 'multipart/form-data; boundary=' + Bound; 
    Result := HTTP.HTTPMethod('POST', URL); 
    if Result then 
      ResultData.LoadFromStream(HTTP.Document); 
  finally 
    HTTP.Free; 
  end; 
end; 

TIdMultipartFormDataStreamIndy に切り替えると、そのクラスを使用できます。

function HttpPostFile(const URL, InputText1FieldName, InputText1, InputText2FieldName, InputText2, InputFileFieldName, InputFileName: string; InputFileData: TStream; ResultData: TStrings): Boolean; 
var 
  HTTP: TIdHTTP; 
  Input: TIdMultipartFormDataStream;
  Output: TMemoryStream;
begin 
  Result := False;
  try
    Output := TMemoryStream.Create;
    try
      HTTP := TIdHTTP.Create; 
      try 
        Input := TIdMultipartFormDataStream.Create;
        try
          Input.AddFormField(InputText1FieldName, InputText1);
          Input.AddFormField(InputText2FieldName, InputText2);
          Input.AddFormField(InputFileFieldName, 'application/octet-stream', '', InputFileData, InputFileName);
          HTTP.Post(URL, Input, Output);
        finally
          Input.Free;
        end;
      finally
        HTTP.Free;
      end;
      Output.Position := 0;
      ResultData.LoadFromStream(Output);
      Result := True; 
    finally
      Output.Free;
    end;
  except
  end; 
end; 
于 2012-07-13T21:33:55.237 に答える
1

私も自分のプロジェクトでシナプスを使用しています。Synapse で作業をシンプルかつ高速にするために、THTTPSendEx クラスを作成しました。これにより、使用速度が速く、最小限のコードとより多くの機能が提供されます。現在はベータ版です。

インディのような景色です。

THTTPSendEx クラスを作成します。そのプロトタイプ (pas ファイルを参照) からメソッド OnBeginWork、OnWork、OnWorkEnd を作成し、作成したクラスに割り当てます。必要なのはそれだけで、クラスの GET、POST 関数を呼び出すだけです。

また、TMultipartFormDataStream クラスとして、この形式でファイルを高速に投稿するための multipart-fomdata も実装しています。それを使用すると、ファイルとフィールドを簡単に書き込むことができます。

使用例:

var
 HTTP:THTTPSendEx;
 Data:TMultipartFormDataStream;
 sHTML:string; //Recived HTML code from web
begin
 HTTP:=THTTPSEndEx.Create;
 Data:=TMultipartFormDataStream.Create;
 try
  Data.AddFile('myFile','Path to the local file(No UNC paths)');
  Data.DataEnd;
  if HTTP.Post('URL HERE',Data,sHTML) then
  begin
  //Connection established
  //Check HTTP response
  if HTTP.IsSuccessfull then  //HTTP returns "200 OK" code.
  begin
    ShowMessage('File successfully posted to the server.');
  end;
  end else
  begin
   ShowMessage('Can not establish a connection to the server...'+#13+'Network is not avaliable or server socket does not exist.');
  end;
 finally
   FreeAndNil(HTTP);
   FreeAndNil(Data);
 end;
end;

私のウェブサイトで見ることができます

これに関するアイデアがあれば、プロジェクト ページへのコメントとして書き込んでください。

英語の間違いをお詫びします。

于 2013-07-31T20:07:47.797 に答える