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.