首页 > 代码库 > delphi idhttp 实战用法

delphi idhttp 实战用法

以delphi xe2 自带indy(10.5.8.0)组件为例,分享实战中遇到的问题及解决方法。

Idhttp 重要属性

HTTPOptions := [];

属性设为空,禁止idhttp自动为post的TStringList参数编码,因为自动编码使用的是HttpApp单元下的HttpEncode,

但此函数有误,未将+,$,@这3个符号编成UrlCode。请自行改造此函数然后使用。

HTTPOptions := [hoNoParseMetaHTTPEquiv];

当遇到Get某个网页,idhttp一直会卡住的时候,请尝试此值。

提供一个会卡住的网址给大家测试:http://www.bf35.com/Company/Detail/23284.html

此网址来之不易,请善加保存!哈哈!

 

Request.RawHeaders.FoldLength := 8192;

参数头的总长度限制,如果post的TStringList参数过长,请加大此值。否则,超长部分将不会被post。

FIdCookieMgr := TIdCookieMgr.Create(self);  //TIdCookieMgr

CookieManager := FIdCookieMgr;

AllowCookies := true;

TIdCookieMgr是我改进了的TIdCookieManager,增加了保存Cookie与加载Cookie的方法。后面详细写出。

 

IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(self);

此为Https功能必备,它需要两个文件 libeay32.dll和ssleay32.dll,

这两个文件在阿里旺旺的安装目录里能够找到。大家不必满世界找了。

 

Request.AcceptEncoding := ‘gzip‘;

在Get与Post的时候,告诉服务器,请把数据压缩后再传给我。

Idhttp自带的解压缩功能是错误的,需要自己去下载一个 Zlib 库,然后自己解压缩。见后面。

idhttp自带的解utf-8编码也是错误的,也需要自己手动解码。见后面

HandleRedirects := true;
ProtocolVersion := pv1_1;
ReadTimeout := 5000;
ConnectTimeout := 5000;
RedirectMaximum := 5;
Request.UserAgent := sUserAgent2;
Request.Accept := sAccept;

这几个属性,不再解释。

 

TIdCookieMgr 实现的功能

此类从TIdCookieMgr继承而来,下面是重点。

function TIdCookieMgr.GetCookieList: TStringList;
var
C: Tcollectionitem;
begin
   result := TStringList.Create;
   for C in CookieCollection do
      result.add((C as TIdCookie).CookieText);
end;

这是当获取到Cookie后,如何取得所有Cookie的文本。这很简单。

下面讲如何把保存后的Cookie文本加载回去

procedure TIdCookieMgr.SetCurCookies(const Value: string);
var
  StrLst: TStringList;
  C: TIdCookie;
  uri: TIdURI;
  s, t: string;
begin
  StrLst := TStringList.Create;
  uri := TIdURI.Create;
try
 

   StrLst.Text := Value;

   CookieCollection.Clear;

   for s in StrLst do
   begin
      C := CookieCollection.add;
      CookieCollection.AddCookie(C, uri);
      C.ParseServerCookie(s, uri);
      C.Domain := GetStrBetween(s, ‘Domain=‘, ‘;‘);
      C.Path := GetStrBetween(s, ‘Path=‘, ‘;‘);

      //GetStrBetween 请自己去实现一个。

      t := GetStrBetween(s, ‘Expires=‘, ‘GMT‘) + ‘GMT‘;
      C.Expires := CookieStrToLocalDateTime(t);
  end;


finally
  uri.Free;
  StrLst.Free;
end;
end;

 

GetHtmlAfterOperateIdhtpp 这个函数重要,请copy下来,等会要用

用于解压Gzip,解码utf8

 

 1 function GetHtmlAfterOperateIdhttp(AIdhttp: TIdHTTP; AStream: TStream): string; 2 var 3   BSize: Int64; 4   BOutStream: TMemoryStream; 5   TempStream: TMemoryStream; 6   rS: RawByteString; //注意这个格式 7   s: string; 8   BIsUtf8: Boolean; 9 begin10   BSize := AStream.Size;11 12   BOutStream := TMemoryStream.Create;13   try14     if BSize > 0 then15     begin16 17       if PosEx(GZIP, UpperCase(AIdhttp.Response.ContentEncoding)) > 0 then18       begin19         AStream.Position := 0;           ZDecompressStream2(AStream, BOutStream, 31); 
      //这个函数在Zlib库的 ZLibEx.pas中,请自行去下载. 31 这个参数,是搜了很多资料才找到的,不知道为什么。免费送给大家用了。
21 TempStream := BOutStream;22 end23 else24 TempStream := TMemoryStream(AStream);25 26 BSize := TempStream.Size;27 SetLength(rS, BSize);28 TempStream.Position := 0;29 TempStream.ReadBuffer(rS[1], BSize);30 31 s := string(rS);32 33 BIsUtf8 := PosEx(UTF-8, UpperCase(AIdhttp.Response.CharSet)) > 0;34 35 BIsUtf8 := BIsUtf8 or (PosEx(charset="utf-8", s) > 0);36 BIsUtf8 := BIsUtf8 or (PosEx(charset=utf-8, s) > 0);
//判断代码是不是Utf8 不是很严谨,请自动修改后使用
37 38 if PosEx(GBK, UpperCase(AIdhttp.Response.CharSet)) > 0 then39 begin40 BIsUtf8 := false;41 end;42 43 if BIsUtf8 then44 result := UTF8ToString(rS)
//注意rS的类型
45 else46 result := s;47 48 end49 finally50 BOutStream.Free;51 end;52 53 end;

 

下面给出三个操作idhttp的函数,用它们就很方便了.

function IdhttpGet(AIdhttp: TIdHTTP; const AUrl: string; var AHtml: string): Boolean;var  BStrStream: TMemoryStream;begin  AHtml := ‘‘;  BStrStream := TMemoryStream.Create;  try    try      AIdhttp.Get(AUrl, BStrStream);      AHtml := GetHtmlAfterOperateIdhttp(AIdhttp, BStrStream);      result := true;    except      on e: Exception do      begin        result := false;        AHtml := e.Message;      end;    end;  finally    BStrStream.Free;  end;end;function IdhttpPost(AIdhttp: TIdHTTP; AStrList: TStringList; const AUrl: string; var AHtml: String): Boolean; overload;var  BStrStream: TMemoryStream;begin  result := true;  AHtml := ‘‘;  BStrStream := TMemoryStream.Create;  try    try      AIdhttp.Post(AUrl, AStrList, BStrStream);      AHtml := GetHtmlAfterOperateIdhttp(AIdhttp, BStrStream);    except      on e: Exception do      begin        AHtml := e.Message;        result := false;      end;    end;  finally    BStrStream.Free;  end;end;function IdhttpPost(AIdhttp: TIdHTTP; AIdMul: TIdMultiPartFormDataStream; const AUrl: string; var AHtml: string)  : Boolean; overload;var  BStrStream: TMemoryStream;begin  result := true;  AHtml := ‘‘;  BStrStream := TMemoryStream.Create;  try    try      AIdhttp.Post(AUrl, AIdMul, BStrStream);      AHtml := GetHtmlAfterOperateIdhttp(AIdhttp, BStrStream);    except      on e: Exception do      begin        AHtml := e.Message;        result := false;      end;    end;  finally    BStrStream.Free;  end;end;

 

别急,还有。如何手工给post参数编码

请自己改造HttpEncode函数,可以是像我这样子的.

function HttpEncodeX(const AStr: string): string;
var
s: string;
begin

   s := String(HttpEncode(AnsiString(UTF8Encode(AStr))));   

  //通常来说,如果参数有中文,是先编成Utf8再urlEncode的。请看清后再使用.

   s := ReplaceAll(s, ‘+‘, ‘%20‘); //此函数请去网上搜一个.

   s := ReplaceAll(s, ‘$‘, ‘%24‘);

   Result := ReplaceAll(s, ‘@‘, ‘%40‘);

end;

 

编码方法:

var

  BStrs:TSTringList;

begin

   BStrs:=TStringlist.Create;

   BStrs.add(‘name=‘+HttpEncodeX(‘晓不得abc‘));

   BStrs.add( HttpEncodeX(‘na$me‘)+‘=‘+HttpEncodeX(‘晓不得abc‘));

   //切记,这里的等号用原型,不要编码。idhttp会自动把等号翻译成 & 放在请求头中.

end;

 

好了,over,祝大家编的外挂功能越来越好用!

 

 

 

 

 

 

 

delphi idhttp 实战用法