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.