【问题标题】:TIdHTTP - session has expired message under Delphi XETIdHTTP - Delphi XE 下的会话已过期消息
【发布时间】:2012-02-01 01:24:19
【问题描述】:

我正在尝试将我的代码从 Delphi 2007 移植到 Delphi XE(还没有更新 1)。我偶然发现的问题是,在 Delphi XE 下,我在发送第二条 GET 消息后得到了来自服务器的不同响应。

格式化 HTML 中的消息表明我的会话已过期。但是,直到今天,相同的代码在 Delphi 2007 下都可以正常工作。我在网上搜索了资料,发现我应该使用 CookieManager?

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

我还能尝试什么?

更新:我发现一些信息表明 Indy 10 的 cookie 存在问题,但已修复。

我已经下载了Indy10_4722的快照,不幸的是错误仍然出现。

更新 2 - 提供代码

所以,我准备了一个示例代码。这与 Delphi(2007 和 XE)兼容。但是要在 2007 下编译它,您需要有 GraphicEx library

代码正在连接到真实服务器,加载安全图像并将其显示在表单中。将图像中的字母重写到编辑框并关闭表单。这就是您测试它所需要做的一切。

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 的数据包示例are here

Delphi XE 数据包示例are here.

分析数据包的免费程序SmartSniff

谢谢。

【问题讨论】:

  • 好的,我会的,但你最好回答我的问题,先生! ;-)
  • TIdHTTP 在内部使用隐式 TIdCookieManager 对象,如果您自己不提供一个对象。 Indy 10 的旧快照确实存在一些与 cookie 相关的问题,但现代快照具有完全重新设计的 cookie 处理系统,该系统基于 2011 年发布的新 cookie RFC,据我所知,它适用于大多数已知系统。如果您认为您仍然有 cookie 问题,那么我们需要查看实际的 cookie 以及围绕它们的相关 HTTP 请求/响应流量,以便我们可以看到 cookie 何时被发送回服务器,或没有被发送回服务器。
  • 谢谢,今天我将提供一个完整的工作示例和完整的不工作示例进行比较。
  • @Wodzu:按时间顺序与 HTTP 状态管理机制相关的 RFC 分别是:RFC 2109(过时)、RFC 2965(过时),最后是 2011 年 4 月发布的 RFC 6265
  • Indy 10 用于实现 RFC 2109 和 2965,以及没有 RFC 的 Netscape 原始 cookie 规范。现在它只实现了 RFC 6265,它涵盖了大多数现代系统在现实世界中实际使用的所有内容。

标签: delphi port delphi-xe delphi-2007 indy


【解决方案1】:

我认为您应该考虑使用httpanalyzerfiddler 等工具检查请求。

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

然后使用您的应用并比较两个请求。如果是 cookie 问题,您会看到问题所在。

Keep-alive 不是你的答案。它只会使您的连接不会在对同一服务器的每个请求中被丢弃。见Wikipedia

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 2017-06-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多