5

好的,我已经像下面这样动态创建了 Idhttp


procedure TForm1.Button1Click(Sender: TObject);
Var
   Resp : String;
begin
     Resp := webSession('https://www.website.com'); // HTTPS site requires session to keep alive
     if Length(Resp)>0 then
        MessageDlg('Got the body ok',mtInformation,[mbOk],0);
end;

function TForm1.webSession(sURL : ansistring) : ansistring;
var
   SStream    : Tstringstream;
   HTTPCon    : TIdHTTP;
   AntiFreeze : TIdAntiFreeze;
   CompressorZLib: TIdCompressorZLib;
   ConnectionIntercept: TIdConnectionIntercept;
   SSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL;
   CookieManager: TIdCookieManager;
begin
    CompressorZLib :=  TIdCompressorZLib.Create;
    ConnectionIntercept :=TIdConnectionIntercept.Create;
    SSLIOHandlerSocketOpenSSL :=  TIdSSLIOHandlerSocketOpenSSL.Create;
     Result := '';
     if Length(SettingsForm.edtProxyServer.text) >= 7 then  // 0.0.0.0
     Try
        SStream := NIL;
        AntiFreeze := NIL;
        HTTPCon := NIL;
        Try
           SStream := tstringstream.Create('');
           { Create & Set IdHTTP properties }
           HTTPCon := TIdHTTP.create;
           HTTPCon.AllowCookies:=true;
           HTTPCon.CookieManager :=CookieManager;
           HTTPCon.Compressor := CompressorZLib;
           HTTPCon.Intercept := ConnectionIntercept;
           HTTPCon.IOHandler := SSLIOHandlerSocketOpenSSL;
           HTTPCon.HandleRedirects := true;
           { Check Proxy }
           if checkproxy('http://www.google.com') then
           Begin
                HTTPCon.ProxyParams.ProxyServer := SettingsForm.edtProxyServer.text;
                HTTPCon.ProxyParams.ProxyPort := StrToInt(SettingsForm.edtProxyPort.Text);
                HTTPCon.ProxyParams.BasicAuthentication := True;
                HTTPCon.ProxyParams.ProxyUsername := SettingsForm.edtProxyServer.Text;
                HTTPCon.ProxyParams.ProxyPassword := SettingsForm.edtProxyUserName.Text;
           End;
           { Create another AntiFreeze - only 1/app }
           AntiFreeze := TIdAntiFreeze.Create(nil);
           AntiFreeze.Active := true;
           HTTPCon.Get(sURL,SStream);
           Result := UTF8ToWideString(SStream.DataString);
        Finally
           If Assigned(HTTPCon) then FreeAndNil(HTTPCon);
           If Assigned(AntiFreeze) then FreeAndNil(AntiFreeze);
           If Assigned(SStream) then FreeAndNil(SStream);
           If Assigned(CookieManager) then FreeAndNil (CookieManager );
           If Assigned(CompressorZLib) then FreeAndNil (CompressorZLib );
           If Assigned(ConnectionIntercept) then FreeAndNil (ConnectionIntercept );
           If Assigned(SSLIOHandlerSocketOpenSSL) then FreeAndNil (SSLIOHandlerSocketOpenSSL);

        End;
     Except
        { Handle exceptions }
        On E:Exception do
           MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
     End;
end;

function TForm1.checkproxy(sURL : ansistring) : boolean;
var
   HTTPCon : TIdHTTP;
   AntiFreeze : TIdAntiFreeze;
begin
     Result := False;
     Try
        { Inti vars }
        AntiFreeze := NIL;
        HTTPCon := NIL;
        Try
           { AntiFreeze }
           AntiFreeze := TIdAntiFreeze.Create(NIL);
           AntiFreeze.Active := true;
           { Create & Set IdHTTP properties }
           HTTPCon := TIdHTTP.Create(NIL);
           HTTPCon.ProxyParams.ProxyServer := SettingsForm.edtProxyServer.text;
           HTTPCon.ProxyParams.ProxyPort := StrToInt(SettingsForm.edtProxyPort.Text);
           HTTPCon.ProxyParams.BasicAuthentication := True;
           HTTPCon.ProxyParams.ProxyUsername := SettingsForm.edtProxyServer.Text;
           HTTPCon.ProxyParams.ProxyPassword := SettingsForm.edtProxyUserName.Text;
           HTTPCon.HandleRedirects := true;
           HTTPCon.ConnectTimeout := 1000;
           HTTPCon.Request.Connection := 'close';
           HTTPCon.Head(sURL);
        Finally
           { Cleanup }
           if Assigned(HTTPCon) then
           Begin
                { Return Success/Failure }
                Result := HTTPCon.ResponseCode = 200;
                If HTTPCon.Connected then HTTPCon.Disconnect;
                FreeAndNil(HTTPCon);
           End;
           if Assigned(AntiFreeze) then FreeAndNil(AntiFreeze);
        End;
     Except
        On E:EIdException do ;
        { Handle exceptions }
        On E:Exception do
           MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
     End;
end;

我有一个网站,要求我保持会话活跃。我该怎么做?使用与上面类似的代码。

如果我为所有东西创建一个可视化组件并使用它,一切都很好,但是当我动态创建组件时(我真的想这样离开它),它无法保持会话活跃。

任何帮助表示赞赏。

4

3 回答 3

5

我看不到您在哪里实例化CookieManager,但那是您应该跟踪会话的地方。服务器将发送一些代表当前会话的 cookie,并且您发送到服务器的所有进一步请求都应包含该 cookie,以便服务器知道要使用哪个会话。

您必须在会话期间保留 cookie-manager 对象,或者您必须将其数据保存在其他地方,然后在每次创建新的 cookie-manager 对象时重新加载它。我更喜欢前者。事实上,您可能会考虑保留整个 HTTP 对象。

于 2010-02-14T02:58:52.403 回答
2

正如您在评论中提到的,您正在 OnCreate 事件处理程序中创建 CookieManager,因此当调用 TForm1.webSession 时,CookieManager 可用,但在 TForm1.webSession 的 finally 块中您正在释放 CookieManager,因此一旦您离开 TForm1。 webSession 方法,CookieManager 内存不足。因此,下次调用 TForm1.webSession 时,CookieManager 为 Nil,并且不会为您保存任何 cookie。

还有另外两个注释与您的问题无关,但与您的源代码有关:

1-您的方法返回 AnsiString,但您使用 Utf8ToWideString 为 Result 变量赋值。Utf8ToWideString 返回 WideString,因此编译器必须将 WideString 转换为 AnsiString,这不仅降低了性能,而且丢失了返回字符串中的 unicode 字符。您应该更改方法签名以返回 String(D2009 和 D2010)或 WideString(旧版本的 Delphi)。

2- 您不需要检查是否在 finally 块中分配了 SStream、AntiFreeze 或 HTTPCon。您可以简单地调用 Free 方法,或使用 FreeAndNil 过程。

问候

于 2010-02-14T13:28:33.560 回答
1

正如 Rob 所说,您的 TIdCookieManager 是维护基于 Cookie 的会话的关键。TIdCookieManager 可以在数据模块的 create 事件或 mainforms OnCreate() 事件中创建,然后在每次创建 IdHTTP 组件时设置。

于 2010-02-14T07:21:48.237 回答