如何使用 Indy 9 发送 DELETE 请求?

How to send a DELETE request with Indy 9?

我正在尝试使用 Indy 9 发送 HTTP DELETE 请求。

尝试(like that):

type
  TIdHTTPAccess = class(TIdHTTP)
  end;

TIdHTTPAccess(IdHttp).DoRequest(hmDelete, deleteURL, nil, nil);

这不起作用,因为 hmDelete 在 TIdHTTPProtocol.BuildAndSendRequest 中被跳过了。

是否有机会使用 Indy 9 发送 HTTP DELETE 请求?

Delpphi 7,Indy 9.00.10,IdHTTP 单元的一部分;

procedure TIdHTTPProtocol.BuildAndSendRequest(AURI: TIdURI);
...
  case Request.Method of
    hmHead: FHTTP.WriteLn('HEAD ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmGet: FHTTP.WriteLn('GET ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmPost: FHTTP.WriteLn('POST ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    // HTTP 1.1 only
    hmOptions: FHTTP.WriteLn('OPTIONS ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmTrace: FHTTP.WriteLn('TRACE ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmPut: FHTTP.WriteLn('PUT ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
    hmConnect: FHTTP.WriteLn('CONNECT ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
  end;
...

直接调用 TIdHTTP.DoRequest() 是在 Indy 9 中发送 DELETE 请求的正确方法。使用访问器 class 是一种选择。另一种选择是从 TIdHTTP 派生一个新组件以添加您自己的 Delete() 调用 DoRequest() 的方法(很像 Indy 10 中的 TIdHTTP):

type
  TMyHTTP = class(TIdHTTP)
  public
    procedure Delete(AURL: string; AResponseContent: TStream); overload;
    function Delete(AURL: string): string; overload;
  end;

procedure TMyHTTP.Delete(AURL: string; AResponseContent: TStream);
begin
  DoRequest(hmDelete, AURL, nil, AResponseContent);
end;

function TMyHTTP.Delete(AURL: string): string;
var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    Delete(AURL, Stream);
    SetLength(Result, Stream.Size);
    Move(PChar(Stream.Memory)^, PChar(Result)^, Stream.Size);
  finally
    Stream.Free;
  end;
end;

然而,话虽如此,您使用的是 Indy 9 的 过时版本 。最新版本是 9.0.50,其 BuildAndSendRequest() 代码与你展示了什么:

const
  ProtocolVersionString: array[TIdHTTPProtocolVersion] of string = ('1.0', '1.1'); {do not localize}
  MethodString: array[TIdHTTPMethod] of String = ('HEAD', 'GET', 'POST', 'OPTIONS', 'TRACE', 'PUT', 'DELETE', 'CONNECT'); {do not localize}

...

procedure TIdHTTPProtocol.BuildAndSendRequest(AURI: TIdURI);
var
  ...
begin
  ...
  FHTTP.WriteLn(MethodString[Request.Method] + ' ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize}
  ...
end;

您遇到的问题在 Indy 9 的 IdHTTP.pas 文件的最后一次修订(2007 年 12 月 24 日在 SVN 修订版 35 中)中得到解决:

Updated TIdHTTPProtocol.BuildAndSendRequest() to use a string array of method names instead of using a 'case of' statement, which was originally missing an entry for 'hmDelete'.

您需要升级到最新版本的 Indy 9(如果不是 Indy 10)。

如果这不是一个选项,那么您将不得不编辑您当前的 IdHTTP.pas 副本以添加缺少的 hmDelete 案例,然后重新编译 Indy。