2010-02-14 3 views
5

확인 세션을 유지, 나는 Idhttp 다음델파이 - 인디 (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; 

처럼 동적으로 생성합니다. 어떻게하면 좋을까요? 위와 유사한 코드를 사용합니다.

모든 것을 시각적 구성 요소로 만들고 모든 것을 훌륭하게 사용하면 구성 요소를 동적으로 만들면 (실제로이 방법으로 남겨두고 싶음) 세션을 계속 유지할 수 없습니다.

도움을 주시면 감사하겠습니다.

답변

5

CookieManager을 인스턴스화하는 위치가 표시되지 않지만 세션을 추적해야합니다. 서버는 현재 세션을 나타내는 일부 쿠키를 보내고 서버에 보내는 모든 추가 요청에는 해당 쿠키가 포함되어야하므로 서버가 사용할 세션을 알 수 있습니다.

세션 기간 동안 쿠키 관리자 객체를 유지해야합니다. 그렇지 않으면 새 쿠키 관리자를 만들 때마다 데이터를 다시로드해야합니다. 목적. 나는 이전을 선호 할 것이다. 실제로 전체 HTTP 객체를 유지하는 것을 고려할 수 있습니다.

+0

나는 (그것을 nil'ing되지 않음) 주위를 떠나 다음에서 onCreate 이벤트에 쿠키 관리자를두고, 및 시도했다 .. 그의 코드를 복사하는 것을 잊었다하지만 보이지 않았다 작업. HTTP 객체를 유지하는 것에 관해서는, 내가 정말로하고 싶지 않았던 것이 었 습니다만, 그렇게 할 수있었습니다. 내가 http 객체를 둘 때 그 동작이 무엇인지 보겠습니다. 나는 정말로 그것을하고 싶지 않았다. (perticular reasoning) ... – Brad

1

Rob는 귀하의 TIdCookieManager가 쿠키 기반 세션을 유지 관리하기위한 열쇠라고 말했습니다. TIdCookieManager는 데이터 모듈의 create 이벤트 또는 mainforms OnCreate() 이벤트에서 생성 된 다음 IdHTTP 구성 요소를 만들 때마다 설정 될 수 있습니다.

+0

나는 다시 OnCreate를 시도 할 것이고, 나는 폼에 OnCreate를했다. (BTW, 전에 코드를 주셔서 감사합니다.이 사이트를 처리하고 세션을 유지해야만 훌륭하게 작동했습니다.) – Brad

+0

도움이 될 수있어서 다행입니다. - 통신 파트에 스레드를 사용 했습니까? 코드에서 구현할 수 있다면 더 부드러운 승차감을 만들 수 있습니까? –

+0

그래, 나는 스레드 데모를보고 있었지만, 스레딩은 델파이의 현재 지식 수준을 넘어서고있다.그리고이 프로젝트가하는 일 중 많은 부분이 같은 웹 사이트에 계속해서 반복적으로 접촉하기 때문에이 사이트에 대해 여러 번 요청할 필요는 없습니다. 하지만 두 개의 다른 프로젝트에서 동일한 기본 코드를 사용하고 스레드를 사용하는 것이 좋습니다. 좋은 스레드 데모에 대한 제안 사항이 있습니까? – Brad

2

의견에서 언급 한대로 OnCreate 이벤트 처리기에서 CookieManager를 작성하므로 TForm1.webSession이 호출 될 때 CookieManager를 사용할 수 있지만 TForm1.webSession의 finally 블록에서 CookieManager를 한 번 해제 할 수 있습니다. 당신은 TForm1.webSession 메서드를 남겨두고 CookieManager는 메모리가 부족합니다. 따라서 다음에 TForm1.webSession이 호출되고 CookieManager는 Nil이며 쿠키가 저장되지 않습니다.

이 질문에 관련이없는 두 개의 다른 음이 있지만, 소스 코드에 관련이 있습니다

1 귀하의 방법을 AnsiString을 반환하지만 변수 결과에 값을 할당하기위한 Utf8ToWideString을 사용하고 있습니다. Utf8ToWideString은 WideString을 반환하므로 컴파일러에서 WideString을 AnsiString으로 변환해야하므로 성능이 저하 될뿐만 아니라 반환되는 문자열에서 유니 코드 문자가 손실됩니다. String (D2009 & D2010) 또는 WideString (Delphi의 이전 버전) 중 하나를 반환하도록 메서드 서명을 변경해야합니다.

2 SStream, AntiFreeze 또는 HTTPCon이 finally 블록에 할당되어 있는지 확인할 필요가 없습니다. Free 메소드를 호출하거나 FreeAndNil 프로 시저를 사용할 수 있습니다.

안부

+0

AnsiString에 대한 정보를 보내 주셔서 감사합니다.이 문제를 해결하기 위해 작업 코드를 수정하겠습니다. OnCretae 이벤트에 CookieManager가있는 코드에서 해당 버전에 freeandnil 코드가 없습니다. – Brad