不兼容的类型:'System.TArray<System.Net.URLClient.TNameValuePair>' 和 'TNameValuePair' 使用基本身份验证 header

Incompatible types: 'System.TArray<System.Net.URLClient.TNameValuePair>' and 'TNameValuePair' when using basic authentication header

我一直在尝试使用 Delphi 中的 NetHTTPRequestNetHTTPClient 组件来发出基本身份验证请求,但我一直在使用 NetHTTPRequest.Get 方法...

基本上,该方法需要三个参数,即URL(String)、内存流和TNetHeader类型的header。

我不知道为什么,但是当我尝试通过我新创建的header时,我得到了标题中提到的错误,即

Incompatible types: 'System.TArray<System.Net.URLClient.TNameValuePair>' and 'TNameValuePair'

我不知道我是否必须投射,如果我必须投射到什么?

当然,如果我不传递基本身份验证 header,服务器只是 returns 401,因为它没有看到任何凭据或 header 进行解码...

代码如下:

procedure TForm1.Button1Click(Sender: TObject);
var
  HTTPResponseString: String;

begin
  if IsLoggedIn = False then
  begin
    if Edit2.Text = '' then
    begin
      ShowMessage('Password cannot be empty');
      exit;
    end;

    BasicAuth := username + ':' + Edit2.Text; // + '£';
    AuthentificationPacket := EncodeBase64(UTF8Bytes(utf8string(BasicAuth)));

    HTTPHeader := TNetHeader.Create('Authorization: Basic', AuthentificationPacket);

    try
      HTTPResponseLogin := NetHTTPRequest1.Get(HTTPLoginRequest, nil, HTTPHeader);

      ShowMessage(HTTPResponselogin.ContentAsString());
      IsLoggedIn := True;

    except
      on E: Exception do
        ShowMessage(E.Message);

    end;

    Button1.Text := 'LOG OFF';
  end
  else if IsLoggedIn then
  begin
    Edit1.Text := '';
    Edit2.Text := '';
    username := '';
    password := '';
    tagid := '';

    Button1.Enabled := False;
    Button1.Text := 'LOG IN';
    IsLoggedIn := False;

    Timer1.Enabled := False;
    IdleTimer := 0;

    Application.OnIdle := nil;
  end;

end;

有问题的行当然是 NetHTTPRequest1.Get(HTTPLoginRequest, nil, HTTPHeader);

其中 HTTPHeader 被标记为不兼容...

感谢任何帮助!

再仔细看看TNetHTTPRequest.Get()declaration

function Get(const AURL: string; const AResponseContent: TStream = nil; const AHeaders: TNetHeaders = nil): IHTTPResponse;

第三个参数取而代之的是 TNetHeaders(plural), but you are passing it a TNetHeader(单数)。它需要 数组 name/value 对。

此外,Basic 不是 Authorization header 名称的一部分,而是其值的一部分。

试试像这样的东西:

procedure TForm1.Button1Click(Sender: TObject);
var
  BasicAuth, AuthentificationPacket: string;
  HTTPHeader: TNetHeader;
begin
  if not IsLoggedIn then
  begin
    if Edit2.Text = '' then
    begin
      ShowMessage('Password cannot be empty');
      Exit;
    end;

    BasicAuth := username + ':' + Edit2.Text; // + '£';
    AuthentificationPacket := 'Basic ' + EncodeBase64(UTF8Bytes(UTF8String(BasicAuth)));

    HTTPHeader := TNetHeader.Create('Authorization', AuthentificationPacket);

    try
      ShowMessage(NetHTTPRequest1.Get(HTTPLoginRequest, nil, [HTTPHeader]).ContentAsString());
    except
      on E: Exception do begin
        ShowMessage(E.Message);
        Exit;
      end;
    end;

    IsLoggedIn := True;
    Button1.Text := 'LOG OFF';
  end
  else
  begin
    Edit1.Text := '';
    Edit2.Text := '';
    username := '';
    password := '';
    tagid := '';

    Button1.Enabled := False;
    Button1.Text := 'LOG IN';
    IsLoggedIn := False;

    Timer1.Enabled := False;
    IdleTimer := 0;

    Application.OnIdle := nil;
  end;
end;

或者,您可以使用 TNetHTTPRequest.CustomHeaders 属性 代替 AHeaders 参数:

procedure TForm1.Button1Click(Sender: TObject);
var
  BasicAuth: string;
begin
  if not IsLoggedIn then
  begin
    if Edit2.Text = '' then
    begin
      ShowMessage('Password cannot be empty');
      Exit;
    end;

    BasicAuth := username + ':' + Edit2.Text; // + '£';
    NetHTTPRequest1.CustomHeaders['Authorization'] := 'Basic ' + EncodeBase64(UTF8Bytes(UTF8String(BasicAuth));

    try
      ShowMessage(NetHTTPRequest1.Get(HTTPLoginRequest).ContentAsString());
    except
      on E: Exception do begin
        ShowMessage(E.Message);
        Exit;
      end;
    end;

    IsLoggedIn := True;
    Button1.Text := 'LOG OFF';
  end
  else
  begin
    Edit1.Text := '';
    Edit2.Text := '';
    username := '';
    password := '';
    tagid := '';

    Button1.Enabled := False;
    Button1.Text := 'LOG IN';
    IsLoggedIn := False;

    Timer1.Enabled := False;
    IdleTimer := 0;

    Application.OnIdle := nil;
  end;
end;