睦壹 發表於 2019-5-20 08:53:00

TNetHttpClient的用法

<p>TNetHttpClient的用法</p>
<p>TNetHttpClient是DELPHI XE8新增加的控件。</p>
<p>在之前,我们一般都是使用IDHTTP控件,但在安卓、IOS等非WINDOWS平台,IDHTTP访问HTTPS却不行了。</p>
<p>大家知道INDY的SSL访问局限于WINDOWS平台,并不支持跨平台HTTPS访问。</p>
<p>鉴于以上原因,所以EMB才推出了TNetHttpClient。</p>
<p>TNetHttpClient既可以阻塞(如同INDY),又可以异步(这就很全面了)。</p>
<p>TNetHttpClient不再和INDY一样依赖OPENSSL。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">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^ &lt;&gt; #0 do
begin
    case Sp^ of
      '+':
      Rp^ := ' ';
      '%':
      begin
          Inc(Sp);
          if Sp^ = '%' then
            Rp^ := '%'
          else
          begin
            Cp := Sp;
            Inc(Sp);
            if (Cp^ &lt;&gt; #0) and (Sp^ &lt;&gt; #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.
</pre>
</div>
<p>  </p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/10892054.html</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/10892054.html
頁: [1]
查看完整版本: TNetHttpClient的用法