目录
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;
请求超时代码打印
文章来源:https://uudwc.com/A/qedr
文章来源地址https://uudwc.com/A/qedr