Delphi XE下的TIdHTTP - 会话已过期消息

11

我试图将我的代码从Delphi 2007移植到Delphi XE(还没有更新1)。我遇到的问题是,在使用Delphi XE发送第二个GET消息后,我收到了服务器不同的响应。

HTML格式的信息显示我的会话已过期。但是,在Delphi 2007下,同样的代码一直可以正常工作。我在互联网上搜索了相关信息,并发现我应该使用CookieManager?

问题在于,我在Delphi 2007中没有使用任何CookieManager,在Delphi XE中分配了一个,但我的代码结果并没有改变。我仍然收到关于过期会话的消息。

我还能尝试什么?

更新:我发现Indy 10存在cookie问题,但已经修复。

我下载了Indy10_4722快照,但错误仍然存在。

更新2-提供的代码

因此,我准备了一个示例代码。这与Delphi(2007和XE)兼容。但是要在2007年之前编译它,您需要拥有GraphicEx库

该代码连接到真实服务器,加载安全图像并在窗体上显示图像。将图像中的字符重写到编辑框中,然后关闭窗体。这就是测试它所需做的一切。

program IndyTest;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs, Menus, ExtCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  {$IFDEF VER220}PngImage{$ELSE}GraphicEx{$ENDIF}, StrUtils;

{$R *.res}

procedure LoadSecurityImage(AImage: TImage; AIdHTTP: TIdHTTP; AImgLink: String);
var
  PNGGraphic: {$IFDEF VER220}TPngImage{$ELSE} TPNGGraphic{$ENDIF};
  ResponseStream: TMemoryStream;
begin
  ResponseStream := TMemoryStream.Create;
  PNGGraphic   := {$IFDEF VER220}TPngImage.Create{$ELSE}TPNGGraphic.Create{$ENDIF};
  try
    AIdHTTP.Get(AImgLink, ResponseStream);
    ResponseStream.Position := 0;
    PNGGraphic.LoadFromStream(ResponseStream);
    AImage.Picture.Assign(PNGGraphic);
  finally
    ResponseStream.Free;
    PNGGraphic.Free;
  end;
end;

function GetImageLink(AIdHTTP: TIdHTTP): String;
var
  WebContentStream: TStringStream;
  Index, Index2: Integer;
begin
  Result := '';
  WebContentStream := TStringStream.Create('');
  try
    AIdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    AIdHTTP.Get('http://czat.wp.pl/i,1,chat.html', WebContentStream);
    Index := Pos('id="secImg">', WebContentStream.DataString);
    if Index > 0 then
    begin
      Index := PosEx('src="', WebContentStream.DataString, Index) + 5;
      Index2 := PosEx('">', WebContentStream.DataString, Index);
      if Index > 10 then
      begin
        Result := Copy(WebContentStream.DataString, Index, Index2 - Index);
      end;
    end;
  finally
    WebContentStream.Free;
  end;
end;

procedure CheckForContent(const ANick, AImageSeed: String; AIdHTTP: TIdHTTP);
var
  WebContent: TStringStream;
  S: String;
begin
  WebContent := TStringStream.Create('');
  try
    AIdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    S := 'http://czat.wp.pl/chat.html?i=31179&auth=nie&nick=' + ANick
      + '&regulamin=tak&simg=' + AImageSeed + '&x=39&y=13';
    AIdHTTP.Get(S, WebContent);
    if Pos('<div class="applet">', WebContent.DataString) > 0 then
      ShowMessage('It works properly.')
    else if Pos('<div id="alert">Sesja wygas', WebContent.DataString) > 0 then
      ShowMessage('Session expired')
    else
      ShowMessage('Unknown result.');
  finally
    WebContent.Free;
  end;
end;

var
  LogForm: TForm;
  SecurityImage: TImage;
  Edit: TEdit;
  IdHTTPWp: TIdHTTP;
begin
  Application.Initialize;
  IdHTTPWp := TIdHTTP.Create(Application);
  IdHTTPWp.AllowCookies := True;
  IdHTTPWp.HandleRedirects := True;
  IdHTTPWp.HTTPOptions := [hoForceEncodeParams];

  LogForm := TForm.Create(Application);
  LogForm.Position := poScreenCenter;
  SecurityImage := TImage.Create(LogForm);
  SecurityImage.Parent := LogForm;
  SecurityImage.AutoSize := True;
  Edit := TEdit.Create(LogForm);
  Edit.Parent := LogForm;
  Edit.Top := 64;
  LoadSecurityImage(SecurityImage, IdHTTPWp, GetImageLink(IdHTTPWp));
  LogForm.ShowModal;
  CheckForContent('TestUser', Edit.Text, IdHTTPWp);
  Application.Run;
end.

更新3

Delphi 2007示例的数据包在此处

Delphi XE示例的数据包在此处

可用于分析数据包的免费程序SmartSniff

谢谢。


好的,但你最好回答我的问题先生!;-) - Wodzu
3
如果没有提供自己的TIdCookieManager对象,TIdHTTP将在内部使用一个隐式 TIdCookieManager 对象。Indy 10 的旧版本存在一些与 cookie 相关的问题,但是现代版本已经采用了基于2011年发布的新cookie RFC的全新设计的cookie处理系统,并且据我所知对大多数已知系统都正常工作。如果您仍然认为存在 cookie 问题,则需要查看实际的 cookie 及其相关的 HTTP 请求/响应流量,以便我们可以确定 cookie 是否被正确发送回服务器。 - Remy Lebeau
@Wodzu:HTTP状态管理机制相关的RFC按时间顺序排列为:RFC 2109(已过时),RFC 2965(已过时)和最后于2011年4月发布的RFC 6265 - menjaraz
当我连接到某个服务器时,每次请求后我的会话都会过期,因为它希望我保持连接。一旦我在TIdHTTP.Request.Connection中添加了keep-alive,我的过期会话就消失了。你试过这个方法吗? - James L.
@JamesL,感谢您的建议。我已经查看过了,但没有帮助。 - Wodzu
显示剩余3条评论
1个回答

1

我认为你应该考虑使用一些工具(例如httpanalyzerfiddler)来检查请求。

首先使用Internet Explorer并查看它如何处理请求。

然后使用你的应用程序并比较两个请求。如果是cookie问题,你将看到出了什么问题。

保持连接不是你的答案。它只是使你的连接不会在每个对同一服务器的请求中断开。请参见Wikipedia


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接