2014-08-29 3600 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

相关问题