TNetHttpClient的用法

TNetHttpClient的用法

TNetHttpClient是DELPHI XE8新增加的控件。

在之前,我们一般都是使用IDHTTP控件,但在安卓、IOS等非WINDOWS平台,IDHTTP访问HTTPS却不行了。

大家知道INDY的SSL访问局限于WINDOWS平台,并不支持跨平台HTTPS访问。

鉴于以上原因,所以EMB才推出了TNetHttpClient。

TNetHttpClient既可以阻塞(如同INDY),又可以异步(这就很全面了)。

TNetHttpClient不再和INDY一样依赖OPENSSL。

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    NetHTTPClient1: TNetHTTPClient;
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    NetHTTPClient2: TNetHTTPClient;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure NetHTTPClient1RequestCompleted(const Sender: TObject;
      const AResponse: IHTTPResponse);
    procedure Button2Click(Sender: TObject);
    procedure NetHTTPClient2RequestCompleted(const Sender: TObject;
      const AResponse: IHTTPResponse);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses System.NetEncoding;

{$R *.dfm}


function UrlDecode(const AStr: AnsiString): AnsiString;
var
  Sp, Rp, Cp: PAnsiChar;
  s: AnsiString;
begin
  SetLength(Result, Length(AStr));
  Sp := PAnsiChar(AStr);
  Rp := PAnsiChar(Result);
  Cp := Sp;
  while Sp^ <> #0 do
  begin
    case Sp^ of
      '+':
        Rp^ := ' ';
      '%':
        begin
          Inc(Sp);
          if Sp^ = '%' then
            Rp^ := '%'
          else
          begin
            Cp := Sp;
            Inc(Sp);
            if (Cp^ <> #0) and (Sp^ <> #0) then
            begin
              s := AnsiChar('$') + Cp^ + Sp^;
              Rp^ := AnsiChar(StrToInt(string(s)));
            end;
          end;
          Cp := Cp;
        end;
    else
      Rp^ := Sp^;
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PAnsiChar(Result));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  vHttp: TNetHTTPClient;
  vUTF8, vGBK: TStringStream;
begin
  vHttp := TNetHTTPClient.Create(nil);
  vUTF8 := TStringStream.Create('', TEncoding.GetEncoding(65001));
  vGBK := TStringStream.Create('', TEncoding.GetEncoding(936));
  try
    Memo1.Lines.Add('----------------阻塞----------------');
    with vHttp do
    begin
      vUTF8.Clear;
      ConnectionTimeout := 2000; // 2秒
      ResponseTimeout := 10000; // 10秒
      AcceptCharSet := 'utf-8';
      AcceptEncoding := '65001';
      AcceptLanguage := 'zh-CN';
      ContentType := 'text/html';
      UserAgent := 'Embarcadero URI Client/1.0';
      try
        Get('http://offeu.com/utf8.txt', vUTF8);
        Memo1.Lines.Add('utf8:' + TNetEncoding.URL.UrlDecode(vUTF8.DataString));
      except
        on E: Exception do
          // Error sending data: (12002) 操作超时.
          // Error receiving data: (12002) 操作超时
          if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'
          then
            Memo1.Lines.Add('utf8:连接失败!')
          else if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'
          then
            Memo1.Lines.Add('utf8:接收失败,请延长接收超时时间!')
          else
            Memo1.Lines.Add('utf8:' + E.Message);
      end;
      vGBK.Clear;
      AcceptCharSet := 'gbk';
      AcceptEncoding := '936';
      AcceptLanguage := 'zh-CN';
      ContentType := 'text/html';
      UserAgent := 'Embarcadero URI Client/1.0';
      Get('http://offeu.com/gbk.txt', vGBK);
      Memo1.Lines.Add('gbk:' + string(UrlDecode(AnsiString(vGBK.DataString))));
    end;
    Memo1.Lines.Add('----------------异步----------------');
    with NetHTTPClient1 do
    begin
      Asynchronous := true;
      ConnectionTimeout := 10000; // 10秒
      ResponseTimeout := 10000; // 10秒
      AcceptCharSet := 'utf-8';
      AcceptEncoding := '65001';
      AcceptLanguage := 'zh-CN';
      ContentType := 'text/html';
      UserAgent := 'Embarcadero URI Client/1.0';
      Get('http://offeu.com/utf8.txt');
    end;
  finally
    vUTF8.Free;
    vGBK.Free;
    vHttp.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  vHttp: TNetHTTPClient;
  vS: TStringStream;
begin
  // 这里用的 APPCODE 是阿里云市场中的api,需要申请。
  vHttp := TNetHTTPClient.Create(nil);
  vS := TStringStream.Create('', TEncoding.GetEncoding(65001));
  try
    with vHttp do
    begin
      Memo1.Lines.Add('--------------SSL阻塞--------------');
      vS.Clear;
      ConnectionTimeout := 10000; // 10秒
      ResponseTimeout := 10000; // 10秒
      CustomHeaders['Authorization'] :=
        'APPCODE 你申请的appcode';
      Accept := 'application/json;';
      ContentType := 'application/json; charset=utf-8;';
      UserAgent := 'Embarcadero URI Client/1.0';
      Get('https://dm-81.data.aliyun.com/rest/160601/ip/getIpInfo.json?'
        + 'ip=60.191.244.5', vS);
      Memo1.Lines.Add('ssl:'
        + string(TNetEncoding.URL.UrlDecode(vS.DataString)));
    end;
  finally
    vS.Free;
    vHttp.Free;
  end;
  Memo1.Lines.Add('--------------SSL异步--------------');
  with NetHTTPClient2 do
  begin
    Asynchronous := true;
    ConnectionTimeout := 10000; // 10秒
    ResponseTimeout := 10000; // 10秒
    CustomHeaders['Authorization'] :=
      'APPCODE 你申请的appcode';
    Accept := 'application/json;';
    ContentType := 'application/json; charset=utf-8;';
    UserAgent := 'Embarcadero URI Client/1.0';
    Get('https://dm-81.data.aliyun.com/rest/160601/ip/getIpInfo.json?'
      + 'ip=60.191.244.5');
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  vHttp: TNetHTTPClient;
  vS: TStringStream;
  vList: TStrings;
begin
  vHttp := TNetHTTPClient.Create(nil);
  vList := TStringList.Create;
  vS := TStringStream.Create;
  try
    Memo1.Lines.Add('----------------Post阻塞----------------');
    vS.Clear;
    with vHttp do
    begin
      ConnectionTimeout := 2000; // 2秒
      ResponseTimeout := 10000; // 10秒
      AcceptCharSet := 'utf-8';
      AcceptEncoding := '65001';
      AcceptLanguage := 'zh-CN';
      ContentType := 'text/html';
      UserAgent := 'Embarcadero URI Client/1.0';
      vList.Clear;
      vList.Values['id'] := 'test';
      vList.Values['pwd'] := 'test';
      vList.Values['cmd'] := '1';
      try
        Post('http://60.191.220.219:8090', vList, vS); // utf8进gbk出
        // Memo1.Lines.Add('post:' + TNetEncoding.URL.UrlDecode(vS.DataString));
        Memo1.Lines.Add('post:' + vS.DataString);
      except
        on E: Exception do
          // Error sending data: (12002) 操作超时.
          // Error receiving data: (12002) 操作超时
          if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'
          then
            Memo1.Lines.Add('post:连接失败!')
          else if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'
          then
            Memo1.Lines.Add('post:接收失败,请延长接收超时时间!')
          else
            Memo1.Lines.Add('post:' + E.Message);
      end;
    end;
  finally
    vS.Free;
    vList.Free;
    vHttp.Free;
  end;
end;

procedure TForm1.NetHTTPClient1RequestCompleted(const Sender: TObject;
  const AResponse: IHTTPResponse);
begin
  Memo1.Lines.Add('utf8:' + TNetEncoding.URL.UrlDecode(
    AResponse.ContentAsString(TEncoding.GetEncoding(65001))));
end;

procedure TForm1.NetHTTPClient2RequestCompleted(const Sender: TObject;
  const AResponse: IHTTPResponse);
begin
  Memo1.Lines.Add('ssl:' + TNetEncoding.URL.UrlDecode(
    AResponse.ContentAsString(TEncoding.GetEncoding(65001))));
end;

end.

  

posted @ 2019-05-20 08:53  delphi中间件  阅读(7118)  评论(0编辑  收藏  举报