本文整理自网络,侵删。
访问一个 WEB 网站,如果采用 HTTP 的话,直接使用 TIdHTTP 这个控件,最简单的用法是:
S := IdHTTP1.Get('www.qq.com');
这里返回的 S 就是对应的网页的文本内容。
如果要访问 https 的网站,则需要 SSL 库。在 Windows 底下,去 https://indy.fulgan.com/SSL/ 下载最新的 SSL 的库。下载后,解压缩,包括两个 dll 文件:ssleay32.dll 和 libeay32.dll;直接放到你的程序编译好的 EXE 相同文件夹底下就可以了。运行期你的程序会自动加载这两个 DLL 完成 SSL 的功能。
设计期,拖一个 TIdSSLIOHandlerSocketOpenSSL 过来,然后设置 IdHTTP1 的属性:
1. IOHandler 这个属性,下拉,选择 IdSSLIOHandlerSocketOpenSSL1;
2. HandleRedirects 属性:设置为 True;默认是 False;
另外,要注意设置一下 IdSSLIOHandlerSocketOpenSSL1 的属性:SSLOptions -> Method 这个属性,设置为:sslvTLSv1_1
然后采用这行代码就搞定:S := IdHTTP1.Get('https://www.qq.com');
--------- 分隔符 ---------------
那么,如果直接采用 TCP 连接,自己写 HTTP 请求内容,该怎么做?
毕竟,HTTP 底下是 TCP。一个 HTTP 请求,客户端向服务器发起的是一次 TCP 连接。
如果是普通的 HTTP 的话,拖一个 TIdTCPClient 过来,将这个 IdTCPClient1 连上服务器,发送正确的 HTTP 请求内容给服务器,然后读服务器发送回来的数据,一次 HTTP 访问就完成了。
大概代码如下:
SL := TStringList.Create; SL.LoadFromFile(ExtractFilePath(Application.ExeName) + 'test3.txt'); S := SL.Text; B := BytesOf(S); IdTCPClient1.Host := 'www.qq.com'; IdTCPClient1.Port := 80; IdTCPClient1.Connect; IdTCPClient1.IOHandler.Write(TIdBytes(B));; SR := ''; while True do begin try St := IdTCPClient1.IOHandler.ReadString(200); SR := SR + ST; except Break; end; end; SR := SR + ST; Memo1.Lines.Add(SR); ShowMessage('访问结束!'); IdTCPClient1.Disconnect;上述代码中,要设置 TCP 客户端控件需要去连接的服务器的地址,这里我写的是 www.qq.com;要设置 TCP 要去连接的服务器的端口号。对于 HTTP 的网站,默认是 80;
留意上述代码里面的 test3.txt,这个是 HTTP 请求的内容。本质上,通过TCP发给服务器正确的 HTTP 请求内容,就能获得服务器正确的页面内容返回。
HTTP 请求的内容,是纯文本。假设我们需要访问一个页面:http://www.qq.com/123.html?id=123&UID=abc,那么,这个 HTTP 请求的文本大致是:
GET /www.qq.com/123.html?id=123&UID=abc
发送完这个文本后,还要继续发送几个 HTTP 的头。HTTP 的头基本上就说 name:value 的格式,中间是冒号分隔。HTTP 头都有哪些详细定义,请自行上网搜索。
发送完 HTTP 的头以后,多发一个空行(也就是发送两个字符:回车,换行)。
上述的 HTTP 请求内容和 HTTP 头,为了避免代码的麻烦,我就把它写入了 test3.txt 里面。
然后可以开始在 TCP 客户端控件上读来自服务器端的内容,也就是网页内容。
经过这样的实验代码,我们可以更深入地了解 HTTP 请求是怎么一回事。
---------------------- 分隔符 -------------------------------
那么,对于 https 呢?是否仍然可以用 TCP 连接去搞定?当然可以。
仍然采用 TIdTCPClient 去建立一条到网站服务器的 TCP 连接。但是,因为要用到 SSL,所以这里我们要指定 IdTCPClient1 的 IoHandler 的属性,是上面我们拖过来的 IdSSLIOHandlerSocketOpenSSL1 这个控件。当然也要记得运行期的 EXE 文件的目录底下要放那两个 SSL 的库的 DLL 文件。
接下来仍然是从 TCP 连接上发送 HTTP 请求文本包括 HTTP 头去服务器,然后读服务器发送回来的网页内容。
这里唯一要注意的是,如果是 HTTP,发送的 HTTP 请求文本是:
'GET /www.qq.com/123.html HTTP/1.1'这么一行字符串。
但是,如果是 https 的请求,这行字符串里面,一定要加上 https:// 也就是说,要把完整的 URL 发送过去。否则服务器会返回 URI 错误的提示文字。也就是说,需要改为:
'GET https://www.qq.com/123.html HTTP/1.1'以下是测试成功的代码:
procedure TForm1.Button9Click(Sender: TObject);var S: string; SL: TStringList; Ib: TIdBytes; B: TBytes;begin SL := TStringList.Create; try SL.Add('GET https://new.qq.com/omn/20190419/CRI2019041900641200 HTTP/1.1 '); SL.Add('Host: www.qq.com'); SL.Add('Accept:*/* '); SL.Add(''); S := SL.Text; finally SL.Free; end; B := BytesOf(S); SetLength(IB, Length(B)); Move(B[0], IB[0], Length(B)); IdTCPClient2.Host := 'www.qq.com'; IdTCPClient2.Port := 443; IdTCPClient2.Connect; IdTCPClient2.IOHandler.Write(Ib); SetLength(IB, 0); IdTCPClient2.IOHandler.ReadBytes(Ib, -1, False); SetLength(B, Length(Ib)); Move(Ib[0], B[0], Length(B)); S := StringOf(B); Memo2.Lines.Add(S);end;上述代码,确实返回了真实页面的内容。
那么,https 访问时,里面的来回几个加密过程在哪里?在 Delphi 的 Indy 的架构下,估计是 IdSSLIOHandlerSocketOpenSSL1 调用 Open SSL 的 DLL 库的代码,帮我们搞定了。我们只需要专注 HTTP 请求本身就可以了。
综上所述,一个 https 的请求,本质上就是客户端到服务器端的 443 端口的一条 TCP 连接,在这条连接上,客户端发送 HTTP 请求的文本和 HTTP 的头,服务器端会返回正确的 HTTP 的应答。当然,这条 TCP 连接上跑的是加密数据,加密是 SSL 的方式。――――――――――――――――
原文链接:https://blog.csdn.net/pcplayer/article/details/89434464
相关阅读 >>
Delphi firedac 连接sql server一些要注意的地方
Delphi webservice 中采用 tsoapattachment 传输文件
Delphi xe7组件tetheringmanager1发送消息
更多相关阅读请进入《Delphi》频道 >>