• Delphi 实现http请求


    目录

    1.http请求头了解

    2.http调用

    2.1IdHttp

    2.1.1初始化

    2.1.2post方法

    2.1.3实际使用

    2.2nethttpclient

    2.2.1初始化

    2.1.2post方法

    2.2.3实际使用


    旧项目维护时发现使用的是TIdHttp,查阅资料发现目前都是使用TNetHTTPClient。他们之间的不同:

     1. nethttpclient支持阻塞和异步模式,idhttp仅支持阻塞模式
     2. nethttpclient可以支持https无需带dll,idhttp需要openssl的几个dll才可以实现
     3. idhttp要手动转码,nethttpclient不需要

    1.http请求头了解

    在把idhttp改成nethttpclient过程中,碰到一些参数了解不全面,故此来整理下请求头包含哪些,进行深入了解和熟悉。

    HTTP Request Header 请求头,这里以百度的请求头为例进行分析

    1. Accept:客户端可以接收服务器返回的类型,例如:text/html,如果是【/】表示接收所有类型。
    2. Accett-Encoding:客户端支持可以压缩的编码,通常指压缩方法,例如gzip
    3. Accept-Language:客户端申明自己接收的语言,例如:zh-CN
    4. Accept-Charset:浏览器可以接受的字符编码集。例如:utf-8
    5. Connection:是否需要持久连接,cloes表示关闭,keep-alive表示连接。
    6. Host:客户端请求资源的Internet主机和端口号,例如:www.baidu.com
    7. Referer:先前网页的网址,即来路。
    8. User-Agent:客户端使用的操作系统和浏览器的名称和版本。
    9. 例如:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
    10. (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
    11. Cache-Control:指定请求和响应遵循的缓存机制,是单向的(请求设置了响应不一定有)。
    12. 例如:private: 默认,响应只能够作为私有的缓存,不能再用户间共享
    13. public:响应会被缓存,并且在多用户间共享。
    14. Content-Type:客户端告诉服务器实际发送数据的类型。例如:application/x-www-form-urlencoded

    2.http调用

    这里采用idhttp和nethttpcilent来进行分别展示。

    2.1IdHttp

    2.1.1初始化

    1. procedure TSeverSession.initIdHttp(http: TIdHttp);
    2. var
    3. strs: TStringList;
    4. begin
    5. with http do
    6. begin
    7. ProtocolVersion := pv1_1;
    8. AllowCookies := True;
    9. Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
    10. Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.63';
    11. Request.ContentType := 'application/x-www-form-urlencoded';
    12. Request.AcceptLanguage := 'zh-CN,zh;q=0.8';
    13. Request.AcceptCharSet := 'utf-8';
    14. HTTPOptions := [hoKeepOrigProtocol, hoInProcessAuth];
    15. Request.CharSet := 'utf-8';
    16. Request.CustomHeaders.UnfoldLines := True;
    17. Request.CustomHeaders.FoldLines := false;
    18. //增加系统鉴权
    19. Request.CustomHeaders.Values['Authorization'] := Concat('Bearer ', self.FSessionToken);
    20. end;
    21. end;

    2.1.2post方法

    1. // 发送post请求的方法
    2. function TSeverSession.postRequest(url: string; param: TStringList): string;
    3. var
    4. http: TIdHttp;
    5. respStream: TMemoryStream;
    6. strStream: TStringStream;
    7. res: string;
    8. s: string;
    9. ret: IHTTPResponse;
    10. begin
    11. http := TIdHttp.Create(nil);
    12. respStream := TMemoryStream.Create;
    13. strStream := TStringStream.Create('', TEncoding.UTF8);
    14. self.initIdHttp(http);
    15. try
    16. http.Post(url, param, strStream);
    17. log4me.log4error('【ServerSession】[postRequest]返回值:' + ret.GetStatusCode.ToString);
    18. if http.ResponseCode <> 200 then
    19. begin
    20. log4me.log4error('【ServerSession】[postRequest]与服务器连接失败');
    21. result := '';
    22. exit;
    23. end;
    24. res := strStream.DataString;
    25. result := res;
    26. finally
    27. respStream.Free;
    28. strStream.Free;
    29. http.Free;
    30. end;
    31. end;

    2.1.3实际使用

    这是一个登陆接口,账户account是一个中文字符的传输,使用idhttp的时候涉及转码。

    1. function TSeverSession.Login(accountName: string; password: string): boolean;
    2. var
    3. param: TStringList;
    4. res: string;
    5. jsonObject: TJSONObject;
    6. userObject: TJSONObject;
    7. msg: string;
    8. i: Integer;
    9. begin
    10. SessionToken := '';
    11. param := TStringList.Create;
    12. jsonObject := nil;
    13. try
    14. param.Add('username=' + HttpEncode(AnsiToUtf8(accountName)));
    15. param.Add('password=' + password);
    16. log4me.log4info('【ServerSession】[Login]:向【/auth】发送请求——[' + HttpDecode(param.GetText) + ']');
    17. res := postRequest(getServerUrl() + '/auth', param);
    18. log4me.log4info('【ServerSession】[Login]:后端返回结果res——[' + res + ']');
    19. end;

    2.2nethttpclient

    2.2.1初始化

    1. { TNetHTTPClient初始化http,默认追加表头、类型等信息 }
    2. procedure TSeverSession.initHttp(http: TNetHTTPClient);
    3. var
    4. strs: TStringList;
    5. begin
    6. with http do
    7. begin
    8. //设置连接超时时间
    9. ConnectionTimeout := 1000;
    10. //设置响应超时时间
    11. ResponseTimeout := 2000;
    12. AllowCookies := True;
    13. Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
    14. UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.63';
    15. ContentType := 'application/x-www-form-urlencoded';
    16. AcceptLanguage := 'zh-CN,zh;q=0.8';
    17. AcceptCharSet := 'utf-8';
    18. //增加系统鉴权
    19. CustomHeaders['Authorization'] := Concat('Bearer ', self.FSessionToken);
    20. end;
    21. end;

    2.1.2post方法

    1. // 发送post请求的方法
    2. function TSeverSession.netPostRequest(url: string; param: TStringList): string;
    3. var
    4. nethttp: TNetHTTPClient;
    5. respStream: TMemoryStream;
    6. strStream: TStringStream;
    7. res: string;
    8. s: string;
    9. ret: IHTTPResponse;
    10. begin
    11. nethttp := TNetHTTPClient.Create(nil);
    12. respStream := TMemoryStream.Create;
    13. strStream := TStringStream.Create('', TEncoding.UTF8);
    14. self.initHttp(nethttp);
    15. try
    16. nethttp.Post(url, param, strStream);
    17. log4me.log4info('【ServerSession】[netPostRequest]返回值:' + ret.GetStatusCode.ToString);
    18. if ret.GetStatusCode <> 200 then
    19. begin
    20. log4me.log4error('【ServerSession】[netPostRequest]与服务器连接失败');
    21. result := '';
    22. exit;
    23. end;
    24. res := strStream.DataString;
    25. result := res;
    26. finally
    27. respStream.Free;
    28. strStream.Free;
    29. nethttp.Free;
    30. end;
    31. end;

    2.2.3实际使用

    这里可以看到http请求就不需要转码了。

    1. function TSeverSession.Login(accountName: string; password: string): boolean;
    2. var
    3. param: TStringList;
    4. res: string;
    5. jsonObject: TJSONObject;
    6. userObject: TJSONObject;
    7. msg: string;
    8. i: Integer;
    9. begin
    10. SessionToken := '';
    11. param := TStringList.Create;
    12. jsonObject := nil;
    13. try
    14. param.Add('username=' + accountName);
    15. param.Add('password=' + password);
    16. log4me.log4info('【ServerSession】[Login]:向【/auth】发送请求——[' + HttpDecode(param.GetText) + ']');
    17. res := netPostRequest(getServerUrl() + '/auth', param);
    18. log4me.log4info('【ServerSession】[Login]:后端返回结果res——[' + res + ']');
    19. end;

    请求超时代码打印

     

  • 相关阅读:
    线程同步之信号量
    2流高手速成记(之五):Springboot整合Shiro实现安全管理
    1.数据结构与算法 基础知识
    c++访问修饰符与继承关系
    计算机网络---TCP
    STM32个人笔记-程序跑飞
    Redis 切片集群的数据倾斜分析
    中国信息通信设备行业发展趋势及投资风险研究报告
    JVM-0522
    100行代码自建Flutter状态管理库
  • 原文地址:https://blog.csdn.net/weixin_43487532/article/details/126989391