Delphi7中IdHTTP组件有个bug,很重要

耗费了我一下午带一晚上,最终证明,Delphi7自带的Indy的组件TIdHTTP有个Bug。
下文转自 http://www.gzctu.com/blog/article.asp?id=63
引用
  IdHTTP组件是Indy组件的一部分,主要用于实现读取HTTP服务器的资源,可以实现浏览器的网络功能。
  IdHTTP是从TIdCustomHTTP继承来的,基本上也就是换了一个比较简单的名字给类和属性而已,它本身没有自己的函数和过程,全是从TIdCustomHTTP继承来的。
  基本上用得到的两个方法是Get(两个重载类型)和Post(四个重载类型),我这回用过的是fuction Get(AURL:String) : String和function Post(AURL:String,post:TStream):String,这两个函数返回的就是AURL指定URL上返回的HTML。所有的Get 和Post都是通过调用DoRequest实现的。但是用Post函数的时候如果发模拟一个post类型的form,一定要设 idhttp.Request.Content-Type:='application/x-www-form-urlencoded',不然会有问题。
  如果接收到一个HTTP 3xx的HTTP码,那么就会产生一个OnRedirect事件,如果设定了idhttp.HandleRedirect:=false(这是默认的)的话,会产生一个EIdProtocolReplyError的例外。如果设置了这个属性为true的话,它会自动根据服务器返回的重定向目标进行Get方式访问,当然也可以在OnRedirect事件的处理代码中进行进一步的处理,这个事件是在第二访问之前产生的,这个事件的处理程序会在先于Get执行。
  下面再说说那个CookieManager属性,这个东西是保存IdHTTP访问网页时获得的cookie,它会自动把这些cookie检测一下,如果是有效的,就是会把它保存在CookieManager.CookieCollection里面。然后在访问一个URL的时候,再通过 CookieManager.GenerateCookieList(URI:TIdURI):String取出来发送到服务器的cookie,就放在 Header里面cookie: 后面发出去。
  但是这里Delphi7安装时带的Indy9.0.10有个问题,它在验证cookie是否有效的时候,会先把从服务器中收到的Set-cookie:和Set-cookie2的行后面的cookie文本建立一个cookie,如果这个 cookie有domain字段,就检查domain的值是否与访问的地址一样,如果不一样,那么访问的地址如果是域名,就把前面的主机头去掉,留下以. 开头的域名再与domain比,如果一样就算有效,否则无效,如果访问地址是IP的话如果与domain值不一样就算无效,如果没有domain字段,那么就是有效的。显然这里有一点不对,就是如果访问地址是域名,domain值可以不以.开头,而且可能再是域名的上一结点。例如,对于从 port.fudan.edu.cn上取到的cookie,如果domain 为.fudan.edu.cn,.edu.cn,.cn,fudan.edu.cn,edu.cn都是有效的,但是它只认.fudan.edu.cn的,其它都认为无效。


注意最后一段,Indy9.0.10的IdHTTP组件只能识别如:http://member1.taobao.com/member/login.jhtml这样网址中的域cookie,如果是http://sign.im.alisoft.com/sign/tvs这样的网址,那么此版本的IdHTTP组件就无能为力了,无法识别出其中的im.alisoft.com域Cookie。需要使用更高版本的Indy控件。

我搜索了一下网络,找到了Indy v10.0.52 for Delphi7,大家可以从下面的网址下载到:
http://www.delphifans.com/SoftView/SoftView_993.html

另外,安装新版本Indy时,请参考下文:
引用
indy是一个很好开源的网络通讯套件,覆盖了TCP、HTTP、UDP、SNMP等协议,上百个控件左右。

最近的版本为:10.2.3。Remobjects 在5.0.29后也加入了支持这个indy版本。



但要替换indy是非常麻烦,原因是,delphi自动携带了低版本的indy,如D7携带了Indy9.X的版本,D2007携带了Indy 10.1.X。



我不喜欢用官方自带的安装程序来安装控件,原因是他们喜欢将编译后 indy*.BPL等文件拷贝系统system32目录,如果你不幸装了多个delphi版本的indy或有其他应用程序也在系统目录引用到 indy*.BPL,会一起一系列的麻烦。碰上这类的大型套件,最好是手动安装最好。



你必须先到indy的官方网站目录下载一个最新的 indy snapshot版本。



安装步骤如下:

1、删除delphi目录Bin下的indy*.BPL文件,这是官方旧版本的文件,放心删除(你不放心可以做备份)。

2、删除delphi目录下的 Id*.DCU文件,一般都是在lib目录里。

3、打开安装目录下的indy10\lib目录,安装DPK包顺序如下:

(1)编译 System\IndySystem110.dpk

(2)编译 Core\IndyCore110.dpk,编译安装Core\dclIndyCore110.dpk(设计包)

(3)编译 Protocols\IndyProtocols110.dpk,编译安装Protocols\dclIndyProtocols110.dpk(设计包)

4、添加路径

如果你编译时候,提示找不到单元文件,那是因为,各个包分散在不同目录,需要在工程指定搜索路径或在类库里设置路径。由于我们是长期使用indy10套件,因此在类库里设置好路径后就一劳永逸:


最后,来一点分析:
在Dephi中使用IdHTTP组件时,如果访问的网站中有Redirect的情况出现,需要将HandleRedirects属性设为true。
很多单点登录的网站中会出现网址的多次Redirect,而且会出现多个域Cookie的情况出现,Delphi7的原装IdHTTP只能解析出基础域名的Cookie域,如果出现其他的如:.edu.cn、.sso.ipcat.cn、.top.hulian56.com这样非根域的Cookie时,需要安装更高版本的Indy。显然上文已经给出了安装方法。

你可能感兴趣的:(应用服务器,网络协议,网络应用,SSO,Delphi)