首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Delphi中使用IHTMLDocument2悄悄阻止cookies警告

在Delphi中使用IHTMLDocument2悄悄阻止cookies警告
EN

Stack Overflow用户
提问于 2014-08-29 15:09:37
回答 2查看 995关注 0票数 2

我用IHTMLDocument2来抓取一组网站。我正在创建IHTMLDocument2实例如下:

代码语言:javascript
复制
    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)吗?

我已经更改了OS (Windows2008SE)的Internet选项,使其在没有提示的情况下阻止cookie,但是消息不断出现。如何在静默模式下创建IHTMLDocument2?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-02 11:44:00

如果需要取消IHTMLDocument用户界面或用户通知,则需要同时实现IOleClientSite和定义为DISPID_AMBIENT_DLCONTROL的环境属性。

来自文档“下载控制”

主机可以通过实现IOleClientSite和定义为DISPID_AMBIENT_DLCONTROL的环境属性来控制下载的某些方面--帧、图像、Java等等。当主机的IDis补丁::Invoke方法被dispidMember设置为DISPID_AMBIENT_DLCONTROL调用时,它应该在pvarResult中放置0或以下值的组合。

在本例中需要的标志是DLCTL_SILENT (也可能是DLCTL_NO_SCRIPTS )。

如前所述,如果您希望从文档(例如,IDispatch )获得事件通知,主机还应该实现 (.Invoke)和(或者其他COM事件接收器对象)。

看看EmbeddedWB源代码,看看这是如何实现的。特别是IEParser.pasUI_Less.pas。它已经完全满足了你的需要。

下面是一个基于UI_Less的简化演示(没有实现IPropertyNotifySink):

代码语言:javascript
复制
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;
票数 4
EN

Stack Overflow用户

发布于 2014-08-29 19:47:59

恐怕你不能轻易地把那条消息藏起来。为什么?

首先,您需要了解为什么该信息甚至显示在特定的网站上。简单地说,是欧盟今年开始使用的关于处理饼干的新法律(不确定具体时间):

指南/曲奇?hidecookiesbanner=true

然后你需要意识到所显示的信息不是任何标准的弹出消息,而是硬编码到网站中。更糟糕的是,每个网站所有者都使用自己的方法来做这件事。

顺便说一句,在你的网络浏览器中禁用cookie并不会阻止这条信息的显示。为什么?如果网站想要查看cookie是否已被分配,则必须将cookie发送到客户端计算机。但法律规定,用户在将cookie发送到客户端计算机之前,必须事先得到警告。

因此,简单地点击我接受焦糖的使用一次就更容易了,这条信息可能不会显示给agina。为什么?因为在sich场景中,webite创建了一个苍穹cookie,它存储您已经同意使用cookie的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25571132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档