2014-08-29 3599 views
1

我正在使用IHTMLDocument2來抓取一組網站。我創建的IHTMLDocument2實例作爲本:在Delphi中使用IHTMLDocument2默認阻止cookie警告

var 
     myDownload : TDownLoadURL; 
     doc: OleVariant; 
    (...) 
     myDownload:= TDownLoadURL.Create(nil); 
     with myDownload do 
     begin 
     URL:=myURL; 
     Filename:= GetTempDirectory+'temp_download_url_complete2.txt'; 
     ExecuteTarget(nil); 
     end; 
(...) 
     doc := coHTMLDocument.Create as IHTMLDocument2; 
     doc.write(html); 
     doc.close; 
(...) 

有彈出一個消息與特定網站:

允許該網站提供個性化您的信息, 你會允許它把一個小文件(稱爲cookie)放在你的電腦上?

我已經改變了操作系統(Windows 2008 SE)的Internet選項來阻止沒有提示的cookies,但消息不斷出現。我如何在靜默模式下創建IHTMLDocument2?

+0

您可以設置靜音標誌嗎? – 2014-08-29 15:15:42

+0

您可以使用websearch http://docwiki.embarcadero.com/Libraries/en/SHDocVw.TWebBrowser.Silent – 2014-08-29 15:56:03

+0

TDownloadURL沒有靜音屬性,對不對? – 2014-08-29 19:11:19

回答

3

如果您需要抑制IHTMLDocument用戶界面或用戶通知,則需要實現IOleClientSite和定義爲DISPID_AMBIENT_DLCONTROL的環境屬性。
從文檔"Download Control"

主機可以控制下載幀,圖像,爪哇, 的某些方面等-通過實現兩者的IOleClientSite和定義爲一個DISPID_AMBIENT_DLCONTROL環境屬性 。當主機的IDispatch :: Invoke 方法在dispidMember設置爲DISPID_AMBIENT_DLCONTROL時調用時, 應將零個或以下值的組合放置在 pvarResult中。

在這種情況下,您需要的標誌是DLCTL_SILENT(也可能是DLCTL_NO_SCRIPTS)。

如前所述,主機也應該實現IDispatch.Invoke)和可選IPropertyNotifySink(或其他COM event sink對象),如果你想從文件獲取事件通知(如DISPID_READYSTATE例如)。

看看EmbeddedWB來源,看看它是如何實現的。特別是IEParser.pasUI_Less.pas。它已經完全符合你的需求。


這裏是基於UI_Less簡化的演示(沒有實施IPropertyNotifySink):

uses ..., ActiveX, MSHTML; 

const 
    DISPID_AMBIENT_DLCONTROL = (-5512); 

type 
    TUILess = class(TComponent, IUnknown, IDispatch, IOleClientSite) 
    protected 
    // IDispatch 
    function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; 
     Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HRESULT; stdcall; 
    // IOleClientSite 
    function SaveObject: HRESULT; stdcall; 
    function GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint; 
     out mk: IMoniker): HRESULT; stdcall; 
    function GetContainer(out container: IOleContainer): HRESULT; stdcall; 
    function ShowObject: HRESULT; stdcall; 
    function OnShowWindow(fShow: BOOL): HRESULT; stdcall; 
    function RequestNewObjectLayout: HRESULT; stdcall; 
    end; 

implementation 

function TUILess.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; 
    Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HRESULT; 
const 
    DLCTL_NO_SCRIPTS = $00000080; 
    DLCTL_NO_JAVA = $00000100; 
    DLCTL_NO_RUNACTIVEXCTLS = $00000200; 
    DLCTL_NO_DLACTIVEXCTLS = $00000400; 
    DLCTL_DOWNLOADONLY = $00000800; 
    DLCTL_SILENT = $40000000; 
var 
    I: Integer; 
begin 
    if DISPID_AMBIENT_DLCONTROL = DispID then 
    begin 
    I := DLCTL_DOWNLOADONLY + DLCTL_NO_SCRIPTS + 
     DLCTL_NO_JAVA + DLCTL_NO_DLACTIVEXCTLS + 
     DLCTL_NO_RUNACTIVEXCTLS + 
     DLCTL_SILENT; 
    PVariant(VarResult)^ := I; 
    Result := S_OK; 
    end 
    else 
    Result := DISP_E_MEMBERNOTFOUND; 
end; 

function TUILess.SaveObject: HRESULT; 
begin 
    Result := E_NOTIMPL; 
end; 

function TUILess.GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint; 
    out mk: IMoniker): HRESULT; 
begin 
    Result := E_NOTIMPL; 
end; 

function TUILess.GetContainer(out container: IOleContainer): HRESULT; 
begin 
    Result := E_NOTIMPL; 
end; 

function TUILess.ShowObject: HRESULT; 
begin 
    Result := E_NOTIMPL; 
end; 

function TUILess.OnShowWindow(fShow: BOOL): HRESULT; 
begin 
    Result := E_NOTIMPL; 
end; 

function TUILess.RequestNewObjectLayout: HRESULT; 
begin 
    Result := E_NOTIMPL; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
const 
    cHTML: WideString = '<b>test</b><script>alert("boo")</script>'; 
var 
    Doc: IHTMLDocument2; 
    DocClientSite: TUILess; 
begin 
    DocClientSite := TUILess.Create(nil); 
    try 
    Doc := coHTMLDocument.Create as IHTMLDocument2; 
    try 
     (Doc as IOleObject).SetClientSite(DocClientSite); 
     (Doc as IOleControl).OnAmbientPropertyChange(DISPID_AMBIENT_DLCONTROL); // Invoke 
     OleVariant(Doc).write(cHTML); 
     Doc.close; 
     ShowMessage(Doc.body.innerHtml); // Test 
    finally 
     (Doc as IOleObject).SetClientSite(nil); 
     Doc := nil; 
    end; 
    finally 
    DocClientSite.Free; 
    end; 
end; 
0

恐怕您無法輕鬆隱藏該信息。爲什麼?

首先,您需要了解甚至在特定網站上顯示該消息的原因。簡短的答案是新的法律回合處理Cookie是歐盟開始有時會用今年(不知道什麼時候):

http://ico.org.uk/for_organisations/privacy_and_electronic_communications/the_guide/cookies?hidecookiesbanner=true

然後,你需要認識到,所顯示的消息不是任何標準的彈出消息,但它被硬編碼到網站中。而且更糟糕的是,每個網站所有者都使用自己的方法來做到這一點。

順便說一句,在您的網頁瀏覽器中禁用cookies不會阻止顯示該消息。爲什麼?如果一個網站想要查看cookie是否被允許,它必須發送一個cookie到客戶端計算機。但是,法律要求用戶在使用cookies之前,必須先向用戶發送警告,然後才能將cookie發送到客戶端計算機。

因此,簡單點擊我可能會更容易,我接受一次cokies的使用,該消息可能不會顯示agina。爲什麼?在這種情況下,webite創建一個permament cookie,存儲您已經同意使用cookie的信息。

+0

他沒有瀏覽器控件,因此他沒有看到該頁面。看起來正在顯示一個彈出對話框。 – 2014-08-29 19:56:41

+0

警告通過操作系統作爲「Windows安全警告」發出。我已將所有安全策略降至最低,但未獲成功(http://tiny.cc/fzedlx) – 2014-08-29 20:24:04

+0

Realy?如果它不是祕密,請分享鏈接到網頁的鏈接?我從來沒有見過這樣的行爲。 – SilverWarior 2014-08-29 20:28:09

相關問題