TNetHttpClient的用法

TNetHttpClient是DELPHI XE8新增加的控件。

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

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

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

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

TNetHttpClient不再和INDY一样依赖OPENSSL。

  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  7. System.Classes, Vcl.Graphics,
  8. Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Net.URLClient,
  9. System.Net.HttpClient, System.Net.HttpClientComponent, Vcl.StdCtrls;
  10.  
  11. type
  12. TForm1 = class(TForm)
  13. NetHTTPClient1: TNetHTTPClient;
  14. Button1: TButton;
  15. Memo1: TMemo;
  16. Button2: TButton;
  17. NetHTTPClient2: TNetHTTPClient;
  18. Button3: TButton;
  19. procedure Button1Click(Sender: TObject);
  20. procedure NetHTTPClient1RequestCompleted(const Sender: TObject;
  21. const AResponse: IHTTPResponse);
  22. procedure Button2Click(Sender: TObject);
  23. procedure NetHTTPClient2RequestCompleted(const Sender: TObject;
  24. const AResponse: IHTTPResponse);
  25. procedure Button3Click(Sender: TObject);
  26. private
  27. { Private declarations }
  28. public
  29. { Public declarations }
  30. end;
  31.  
  32. var
  33. Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. uses System.NetEncoding;
  38.  
  39. {$R *.dfm}
  40.  
  41. function UrlDecode(const AStr: AnsiString): AnsiString;
  42. var
  43. Sp, Rp, Cp: PAnsiChar;
  44. s: AnsiString;
  45. begin
  46. SetLength(Result, Length(AStr));
  47. Sp := PAnsiChar(AStr);
  48. Rp := PAnsiChar(Result);
  49. Cp := Sp;
  50. while Sp^ <> #0 do
  51. begin
  52. case Sp^ of
  53. '+':
  54. Rp^ := ' ';
  55. '%':
  56. begin
  57. Inc(Sp);
  58. if Sp^ = '%' then
  59. Rp^ := '%'
  60. else
  61. begin
  62. Cp := Sp;
  63. Inc(Sp);
  64. if (Cp^ <> #0) and (Sp^ <> #0) then
  65. begin
  66. s := AnsiChar('$') + Cp^ + Sp^;
  67. Rp^ := AnsiChar(StrToInt(string(s)));
  68. end;
  69. end;
  70. Cp := Cp;
  71. end;
  72. else
  73. Rp^ := Sp^;
  74. end;
  75. Inc(Rp);
  76. Inc(Sp);
  77. end;
  78. SetLength(Result, Rp - PAnsiChar(Result));
  79. end;
  80.  
  81. procedure TForm1.Button1Click(Sender: TObject);
  82. var
  83. vHttp: TNetHTTPClient;
  84. vUTF8, vGBK: TStringStream;
  85. begin
  86. vHttp := TNetHTTPClient.Create(nil);
  87. vUTF8 := TStringStream.Create('', TEncoding.GetEncoding(65001));
  88. vGBK := TStringStream.Create('', TEncoding.GetEncoding(936));
  89. try
  90. Memo1.Lines.Add('----------------阻塞----------------');
  91. with vHttp do
  92. begin
  93. vUTF8.Clear;
  94. ConnectionTimeout := 2000; // 2秒
  95. ResponseTimeout := 10000; // 10秒
  96. AcceptCharSet := 'utf-8';
  97. AcceptEncoding := '65001';
  98. AcceptLanguage := 'zh-CN';
  99. ContentType := 'text/html';
  100. UserAgent := 'Embarcadero URI Client/1.0';
  101. try
  102. Get('http://offeu.com/utf8.txt', vUTF8);
  103. Memo1.Lines.Add('utf8:' + TNetEncoding.URL.UrlDecode(vUTF8.DataString));
  104. except
  105. on E: Exception do
  106. // Error sending data: (12002) 操作超时.
  107. // Error receiving data: (12002) 操作超时
  108. if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'
  109. then
  110. Memo1.Lines.Add('utf8:连接失败!')
  111. else if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'
  112. then
  113. Memo1.Lines.Add('utf8:接收失败,请延长接收超时时间!')
  114. else
  115. Memo1.Lines.Add('utf8:' + E.Message);
  116. end;
  117. vGBK.Clear;
  118. AcceptCharSet := 'gbk';
  119. AcceptEncoding := '936';
  120. AcceptLanguage := 'zh-CN';
  121. ContentType := 'text/html';
  122. UserAgent := 'Embarcadero URI Client/1.0';
  123. Get('http://offeu.com/gbk.txt', vGBK);
  124. Memo1.Lines.Add('gbk:' + string(UrlDecode(AnsiString(vGBK.DataString))));
  125. end;
  126. Memo1.Lines.Add('----------------异步----------------');
  127. with NetHTTPClient1 do
  128. begin
  129. Asynchronous := true;
  130. ConnectionTimeout := 10000; // 10秒
  131. ResponseTimeout := 10000; // 10秒
  132. AcceptCharSet := 'utf-8';
  133. AcceptEncoding := '65001';
  134. AcceptLanguage := 'zh-CN';
  135. ContentType := 'text/html';
  136. UserAgent := 'Embarcadero URI Client/1.0';
  137. Get('http://offeu.com/utf8.txt');
  138. end;
  139. finally
  140. vUTF8.Free;
  141. vGBK.Free;
  142. vHttp.Free;
  143. end;
  144. end;
  145.  
  146. procedure TForm1.Button2Click(Sender: TObject);
  147. var
  148. vHttp: TNetHTTPClient;
  149. vS: TStringStream;
  150. begin
  151. // 这里用的 APPCODE 是阿里云市场中的api,需要申请。
  152. vHttp := TNetHTTPClient.Create(nil);
  153. vS := TStringStream.Create('', TEncoding.GetEncoding(65001));
  154. try
  155. with vHttp do
  156. begin
  157. Memo1.Lines.Add('--------------SSL阻塞--------------');
  158. vS.Clear;
  159. ConnectionTimeout := 10000; // 10秒
  160. ResponseTimeout := 10000; // 10秒
  161. CustomHeaders['Authorization'] :=
  162. 'APPCODE 你申请的appcode';
  163. Accept := 'application/json;';
  164. ContentType := 'application/json; charset=utf-8;';
  165. UserAgent := 'Embarcadero URI Client/1.0';
  166. Get('https://dm-81.data.aliyun.com/rest/160601/ip/getIpInfo.json?'
  167. + 'ip=60.191.244.5', vS);
  168. Memo1.Lines.Add('ssl:'
  169. + string(TNetEncoding.URL.UrlDecode(vS.DataString)));
  170. end;
  171. finally
  172. vS.Free;
  173. vHttp.Free;
  174. end;
  175. Memo1.Lines.Add('--------------SSL异步--------------');
  176. with NetHTTPClient2 do
  177. begin
  178. Asynchronous := true;
  179. ConnectionTimeout := 10000; // 10秒
  180. ResponseTimeout := 10000; // 10秒
  181. CustomHeaders['Authorization'] :=
  182. 'APPCODE 你申请的appcode';
  183. Accept := 'application/json;';
  184. ContentType := 'application/json; charset=utf-8;';
  185. UserAgent := 'Embarcadero URI Client/1.0';
  186. Get('https://dm-81.data.aliyun.com/rest/160601/ip/getIpInfo.json?'
  187. + 'ip=60.191.244.5');
  188. end;
  189. end;
  190.  
  191. procedure TForm1.Button3Click(Sender: TObject);
  192. var
  193. vHttp: TNetHTTPClient;
  194. vS: TStringStream;
  195. vList: TStrings;
  196. begin
  197. vHttp := TNetHTTPClient.Create(nil);
  198. vList := TStringList.Create;
  199. vS := TStringStream.Create;
  200. try
  201. Memo1.Lines.Add('----------------Post阻塞----------------');
  202. vS.Clear;
  203. with vHttp do
  204. begin
  205. ConnectionTimeout := 2000; // 2秒
  206. ResponseTimeout := 10000; // 10秒
  207. AcceptCharSet := 'utf-8';
  208. AcceptEncoding := '65001';
  209. AcceptLanguage := 'zh-CN';
  210. ContentType := 'text/html';
  211. UserAgent := 'Embarcadero URI Client/1.0';
  212. vList.Clear;
  213. vList.Values['id'] := 'test';
  214. vList.Values['pwd'] := 'test';
  215. vList.Values['cmd'] := '1';
  216. try
  217. Post('http://60.191.220.219:8090', vList, vS); // utf8进gbk出
  218. // Memo1.Lines.Add('post:' + TNetEncoding.URL.UrlDecode(vS.DataString));
  219. Memo1.Lines.Add('post:' + vS.DataString);
  220. except
  221. on E: Exception do
  222. // Error sending data: (12002) 操作超时.
  223. // Error receiving data: (12002) 操作超时
  224. if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error sending data'
  225. then
  226. Memo1.Lines.Add('post:连接失败!')
  227. else if Copy(E.Message, 1, Pos(':', E.Message) - 1) = 'Error receiving data'
  228. then
  229. Memo1.Lines.Add('post:接收失败,请延长接收超时时间!')
  230. else
  231. Memo1.Lines.Add('post:' + E.Message);
  232. end;
  233. end;
  234. finally
  235. vS.Free;
  236. vList.Free;
  237. vHttp.Free;
  238. end;
  239. end;
  240.  
  241. procedure TForm1.NetHTTPClient1RequestCompleted(const Sender: TObject;
  242. const AResponse: IHTTPResponse);
  243. begin
  244. Memo1.Lines.Add('utf8:' + TNetEncoding.URL.UrlDecode(
  245. AResponse.ContentAsString(TEncoding.GetEncoding(65001))));
  246. end;
  247.  
  248. procedure TForm1.NetHTTPClient2RequestCompleted(const Sender: TObject;
  249. const AResponse: IHTTPResponse);
  250. begin
  251. Memo1.Lines.Add('ssl:' + TNetEncoding.URL.UrlDecode(
  252. AResponse.ContentAsString(TEncoding.GetEncoding(65001))));
  253. end;
  254.  
  255. end.

  

TNetHttpClient的用法的更多相关文章

  1. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

  2. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

  3. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  4. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  5. python enumerate 用法

    A new built-in function, enumerate() , will make certain loops a bit clearer. enumerate(thing) , whe ...

  6. [转载]Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结

    本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数: ...

  7. 【JavaScript】innerHTML、innerText和outerHTML的用法区别

    用法: <div id="test">   <span style="color:red">test1</span> tes ...

  8. chattr用法

    [root@localhost tmp]# umask 0022 一.chattr用法 1.创建空文件attrtest,然后删除,提示无法删除,因为有隐藏文件 [root@localhost tmp] ...

  9. 萌新笔记——vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)

    vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于"="."d"."y",我在无意中发现了它们所具有的相同的一些用法,先举 ...

随机推荐

  1. oracle exists和 not exists 的用法

    比如 a,b 关联列为 a.id = b.id,现在要取 a 中的数据,其中id在b中也存在: select * from a where exists(select 1 from b where b ...

  2. iOS中的分类(category)和类扩展(extension)

    今天在研究swift的时候看到了分类和扩展.这是两个十分重要有用的功能,但是之前用的不多,没有深入了解过,在今天就从头理一遍. 一.分类(Category): 概念: 分类(Category)是OC中 ...

  3. CentOS linux7 设置开机启动服务

    常用命令 描述                                 旧命令  新命令 使服务自动启动          chkconfig --level 3 http on  syste ...

  4. 网络编程基础之TCP编程学习(一)

    网络编程基础了解 socket套接字 socket是一种通讯机制,它包含一整套的调用接口和数据结构的定义,他给应用程序提供了使用如TCP/UDP等网络通讯的手段. linux中的网络编程通过socke ...

  5. flash多进程写操作

    1 应用场景介绍   硬件条件:使用stm32 MCU   软件条件:协议栈应用   协议栈简单介绍如下:   类似于OSI七层模型,所涉及的协议栈包括应用层,网络层,链路层,物理层,如下图:   在 ...

  6. linux下18种监测网络带宽方式

    1. nload nload是一个命令行工具,让用户可以分开来监控入站流量和出站流量.它还可以绘制图表以显示入站流量和出站流量,视图比例可以调整.用起来很简单,不支持许多选项. 所以,如果你只需要快速 ...

  7. Linux系统进程的知识总结,进程与线程之间的纠葛...

    来源:嵌入式ARM 当一个程序开始执行后,在开始执行到执行完毕退出这段时间内,它在内存中的部分就叫称作一个进程. Linux 是一个多任务的操作系统,也就是说,在同一时间内,可以有多个进程同时执行.我 ...

  8. JDK源码那些事儿之红黑树基础下篇

    说到HashMap,就一定要说到红黑树,红黑树作为一种自平衡二叉查找树,是一种用途较广的数据结构,在jdk1.8中使用红黑树提升HashMap的性能,今天就来说一说红黑树,上一讲已经给出插入平衡的调整 ...

  9. [唐胡璐]Selenium技巧 - 处理Windows程序(进程)

    Selenium WebDriver java 提供了一个专门的WindowsUtils类去和Windows操作系统交互。 就像我们之前说过有时候跑完脚本后,IEDriverServer.exe进程没 ...

  10. kubectl 自动补全

    kubectl 这个命令行工具非常重要,与之相关的命令也很多,我们也记不住那么多的命令,而且也会经常写错,所以命令自动补全是很有必要的,kubectl 工具本身就支持自动补全,只需简单设置一下即可. ...