delphi idhttp 实战用法

时间:2014-11-09 16:34:50   收藏:0   阅读:6362

以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 begin
10   BSize := AStream.Size;
11 
12   BOutStream := TMemoryStream.Create;
13   try
14     if BSize > 0 then
15     begin
16 
17       if PosEx(GZIP, UpperCase(AIdhttp.Response.ContentEncoding)) > 0 then
18       begin
19         AStream.Position := 0;
           ZDecompressStream2(AStream, BOutStream, 31); 
      //这个函数在Zlib库的 ZLibEx.pas中,请自行去下载. 31 这个参数,是搜了很多资料才找到的,不知道为什么。免费送给大家用了。
21 TempStream := BOutStream; 22 end 23 else 24 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 then 39 begin 40 BIsUtf8 := false; 41 end; 42 43 if BIsUtf8 then 44 result := UTF8ToString(rS)
//注意rS的类型
45 else 46 result := s; 47 48 end 49 finally 50 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,祝大家编的外挂功能越来越好用!

 

 

 

 

 

 

 

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!