2010-02-14 16 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

मुझे लगता है कि के लिए कोड को कॉपी करना भूल गया .. मैं onCreate घटना में कुकी प्रबंधक डाल, और फिर इसे चारों ओर छोड़ने (यह nil'ing नहीं) की कोशिश की थी, लेकिन यह नहीं लगता था काम। HTTP ऑब्जेक्ट को चारों ओर रखने के लिए, यह कुछ ऐसा था जो मैं वास्तव में करना नहीं चाहता था, लेकिन मुझे लगता है कि मैं ऐसा कर सकता हूं। जब मैं http ऑब्जेक्ट को चारों ओर रखता हूं तो मैं देखता हूं कि यह क्या करता है। मैं वास्तव में ऐसा नहीं करना चाहता था (कोई उचित तर्क नहीं) .... – Brad

1

जैसा कि रॉब ने कहा था कि आपका टीआईडीक्यूकी प्रबंधक कुकी आधारित सत्र बनाए रखने के लिए महत्वपूर्ण है। TIdCookieManager को डेटामैड्यूल के निर्माण ईवेंट या मुख्य प्रारूप ऑनक्रेट() ईवेंट में बनाया जा सकता है और फिर प्रत्येक बार जब आप एक आईडीएचटीटीपी घटक बनाते हैं तो सेट किया जा सकता है।

+0

मैं फिर से ऑनक्रेट को आजमाउंगा, मेरे पास फॉर्म पर ऑनक्रेट के रूप में था। (बीटीडब्लू, पहले कोड के लिए धन्यवाद, यह आश्चर्यजनक रूप से काम करता है जब तक कि मुझे इस साइट से निपटना और सत्र बनाए रखना पड़े।) – Brad

+0

कोई समस्या नहीं, मदद की खुशी है! - क्या आपने संचार भागों के लिए धागे का उपयोग करने में देखा है? अगर यह आपके कोड में लागू किया जा सकता है तो एक आसान सवारी के लिए तैयार हो सकता है? –

+0

हाँ, मैं थ्रेडेड डेमो को देख रहा हूं, लेकिन डेल्फी में थ्रेडिंग सिर्फ मेरे वर्तमान ज्ञान स्तर पर है।और इस परियोजना से बहुत कुछ एक ही वेबसाइट पर बार-बार संपर्क करता है, इसलिए मुझे इसके लिए एकाधिक अनुरोध की आवश्यकता नहीं है। लेकिन मैं कुछ अन्य परियोजनाओं में एक ही बेस कोड का उपयोग करता हूं, और उन्हें थ्रेड करना अच्छा लगेगा। क्या आपके पास अच्छे धागे डेमो पर कोई सुझाव है? – Brad

2

आप अपनी टिप्पणी में उल्लेख किया है, आप, OnCreate घटना हैंडलर में CookieManager पैदा कर रहे है ताकि जब TForm1.webSession कहा जाता है, CookieManager उपलब्ध है, लेकिन अंत में TForm1.webSession के ब्लॉक में आप CookieManager मुक्त कराने रहे हैं, इसलिए एक बार आप TForm1.web सत्र विधि छोड़ते हैं, कुकी मैनेजर स्मृति से बाहर है। तो, अगली बार TForm1.webSession कहा जाता है, कुकी मैनेजर नील है, और आपके लिए कोई कुकी सहेजी नहीं जाती है।

दो अन्य नोटों कि आपके प्रश्न से संबंधित नहीं कर रहे हैं, लेकिन अपने स्रोत कोड से संबंधित हैं:

1- आपका विधि AnsiString लौटा रहा है, लेकिन आप मान निर्दिष्ट चर परिणाम के लिए Utf8ToWideString उपयोग कर रहे हैं। Utf8ToWideString WideString देता है, इसलिए कंपाइलर को वाइडस्ट्रिंग को AnsiString में परिवर्तित करना होता है, न केवल यह प्रदर्शन को कम करता है, बल्कि यह लौटने वाली स्ट्रिंग में यूनिकोड वर्ण खो देता है। स्ट्रिंग (डी 200 9 & डी 2010) या वाइडस्ट्रिंग (डेल्फी के पुराने संस्करण) को वापस करने के लिए आपको अपना विधि हस्ताक्षर बदलना चाहिए।

2- आपको यह जांचने की आवश्यकता नहीं है कि आखिरकार ब्लॉक में एसएसट्रीम, एंटीफ्रीज़, या HTTPCon असाइन किए गए हैं या नहीं। आप बस नि: शुल्क विधि को कॉल कर सकते हैं, या FreeAndNil प्रक्रिया का उपयोग कर सकते हैं।

सादर

+0

AnsiString पर जानकारी के लिए धन्यवाद, मैं इसे ठीक करने के लिए कार्य कोड संपादित करूंगा। कोड में मेरे पास ऑनक्रेटे ईवेंट में कुकी मैनेजर था, उस संस्करण में मेरे पास फ्रींडनल कोड नहीं था। – Brad

संबंधित मुद्दे