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 请求头,这里以百度的请求头为例进行分析

Accept:客户端可以接收服务器返回的类型,例如:text/html,如果是【/】表示接收所有类型。

Accett-Encoding:客户端支持可以压缩的编码,通常指压缩方法,例如gzip

Accept-Language:客户端申明自己接收的语言,例如:zh-CN

Accept-Charset:浏览器可以接受的字符编码集。例如:utf-8

Connection:是否需要持久连接,cloes表示关闭,keep-alive表示连接。

Host:客户端请求资源的Internet主机和端口号,例如:www.baidu.com

Referer:先前网页的网址,即来路。

User-Agent:客户端使用的操作系统和浏览器的名称和版本。
例如:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36

Cache-Control:指定请求和响应遵循的缓存机制,是单向的(请求设置了响应不一定有)。
例如:private: 默认,响应只能够作为私有的缓存,不能再用户间共享
public:响应会被缓存,并且在多用户间共享。

Content-Type:客户端告诉服务器实际发送数据的类型。例如:application/x-www-form-urlencoded

2.http调用

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

2.1IdHttp

2.1.1初始化

procedure TSeverSession.initIdHttp(http: TIdHttp);
var
  strs: TStringList;
begin
  with http do
  begin
    ProtocolVersion := pv1_1;
    AllowCookies := True;
    Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
    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';
    Request.ContentType := 'application/x-www-form-urlencoded';
    Request.AcceptLanguage := 'zh-CN,zh;q=0.8';
    Request.AcceptCharSet := 'utf-8';
    HTTPOptions := [hoKeepOrigProtocol, hoInProcessAuth];
    Request.CharSet := 'utf-8';
    Request.CustomHeaders.UnfoldLines := True;
    Request.CustomHeaders.FoldLines := false;
    //增加系统鉴权
    Request.CustomHeaders.Values['Authorization'] := Concat('Bearer ', self.FSessionToken);
  end;
end;

2.1.2post方法

// 发送post请求的方法
function TSeverSession.postRequest(url: string; param: TStringList): string;
var
  http: TIdHttp;
  respStream: TMemoryStream;
  strStream: TStringStream;
  res: string;
  s: string;
  ret: IHTTPResponse;
begin
  http := TIdHttp.Create(nil);
  respStream := TMemoryStream.Create;
  strStream := TStringStream.Create('', TEncoding.UTF8);
  self.initIdHttp(http);
  try
    http.Post(url, param, strStream);
    log4me.log4error('【ServerSession】[postRequest]返回值:' + ret.GetStatusCode.ToString);
    if http.ResponseCode <> 200 then
    begin
      log4me.log4error('【ServerSession】[postRequest]与服务器连接失败');
      result := '';
      exit;
    end;
    res := strStream.DataString;
    result := res;
  finally
    respStream.Free;
    strStream.Free;
    http.Free;
  end;
end;

2.1.3实际使用

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

function TSeverSession.Login(accountName: string; password: string): boolean;
var
  param: TStringList;
  res: string;
  jsonObject: TJSONObject;
  userObject: TJSONObject;
  msg: string;
  i: Integer;
begin
  SessionToken := '';
  param := TStringList.Create;
  jsonObject := nil;
  try
    param.Add('username=' + HttpEncode(AnsiToUtf8(accountName)));
    param.Add('password=' + password);
    log4me.log4info('【ServerSession】[Login]:向【/auth】发送请求——[' + HttpDecode(param.GetText) + ']');
    res := postRequest(getServerUrl() + '/auth', param);
    log4me.log4info('【ServerSession】[Login]:后端返回结果res——[' + res + ']');
end;

2.2nethttpclient

2.2.1初始化

{ TNetHTTPClient初始化http,默认追加表头、类型等信息 }
procedure TSeverSession.initHttp(http: TNetHTTPClient);
var
  strs: TStringList;
begin
  with http do
  begin
    //设置连接超时时间
    ConnectionTimeout := 1000;
    //设置响应超时时间
    ResponseTimeout := 2000;
    AllowCookies := True;
    Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
    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';
    ContentType := 'application/x-www-form-urlencoded';
    AcceptLanguage := 'zh-CN,zh;q=0.8';
    AcceptCharSet := 'utf-8';
    //增加系统鉴权
    CustomHeaders['Authorization'] := Concat('Bearer ', self.FSessionToken);
  end;
end;

2.1.2post方法

// 发送post请求的方法
function TSeverSession.netPostRequest(url: string; param: TStringList): string;
var
  nethttp: TNetHTTPClient;
  respStream: TMemoryStream;
  strStream: TStringStream;
  res: string;
  s: string;
  ret: IHTTPResponse;
begin
  nethttp := TNetHTTPClient.Create(nil);
  respStream := TMemoryStream.Create;
  strStream := TStringStream.Create('', TEncoding.UTF8);
  self.initHttp(nethttp);
  try
    nethttp.Post(url, param, strStream);
    log4me.log4info('【ServerSession】[netPostRequest]返回值:' + ret.GetStatusCode.ToString);
    if ret.GetStatusCode <> 200 then
    begin
      log4me.log4error('【ServerSession】[netPostRequest]与服务器连接失败');
      result := '';
      exit;
    end;
    res := strStream.DataString;
    result := res;
  finally
    respStream.Free;
    strStream.Free;
    nethttp.Free;
  end;
end;

2.2.3实际使用

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

function TSeverSession.Login(accountName: string; password: string): boolean;
var
  param: TStringList;
  res: string;
  jsonObject: TJSONObject;
  userObject: TJSONObject;
  msg: string;
  i: Integer;
begin
  SessionToken := '';
  param := TStringList.Create;
  jsonObject := nil;
  try
    param.Add('username=' + accountName);
    param.Add('password=' + password);
    log4me.log4info('【ServerSession】[Login]:向【/auth】发送请求——[' + HttpDecode(param.GetText) + ']');
    res := netPostRequest(getServerUrl() + '/auth', param);
    log4me.log4info('【ServerSession】[Login]:后端返回结果res——[' + res + ']');
end;

请求超时代码打印

猜你喜欢

转载自blog.csdn.net/weixin_43487532/article/details/126989391