我正在尝试阻止由TEmbeddedWB或TWebBrowser(或TCppWebBrowser)加载的任何外部内容。我想要阻止从互联网加载的任何内容,包括图像、javascript、外部CSS、外部[embed]或[object]或[applet]或[frame]或[iframe],执行可以加载外部内容的JavaScript等。
这个问题包含两个部分:
1. 将Web浏览器置于“限制所有”模式(除了基本的HTML没有图像),并检测是否存在此类内容。 2. 如果不存在外部内容,则正常显示;如果存在,则显示一个“下载栏”,点击后将Web浏览器置于“下载所有”模式并获取所有内容。
第一项存在问题。在TEmbeddedWB中,您可以使用DownloadOptions开关阻止几乎所有内容,其中最重要的是ForceOffline开关,但即使关闭所有开关,它仍会通过一些内容,如[object]或[iframe]标记。我知道这是这种情况,因为我实现了OnBeforeNavigate2事件,并且它会触发这些标记中包含的URL,并在本地服务器日志中进行记录。在TEmbeddedWB中设置OfflineMode和ForceOfflineMode对于这些项目无效。
那么我该如何真正阻止所有内容?因此,它需要作为基本HTML开始,其中包括被阻止的外部元素,包括脚本和CSS。有没有一种方法可以在每次下载任何内容时触发事件,以便可以阻止它或通过阻止所有外部下载来避免首先触发此类事件?我需要调整Internet Explorer区域和安全性吗?任何指向正确方向的指针都将有所帮助。
第二项也很棘手,因为我需要检测是否存在问题标记(例如“applet”、“script”、“link”等)。这种检测不需要完美,但必须足够好以涵盖大多数此类标记。我是这样做的:
这个问题包含两个部分:
1. 将Web浏览器置于“限制所有”模式(除了基本的HTML没有图像),并检测是否存在此类内容。 2. 如果不存在外部内容,则正常显示;如果存在,则显示一个“下载栏”,点击后将Web浏览器置于“下载所有”模式并获取所有内容。
第一项存在问题。在TEmbeddedWB中,您可以使用DownloadOptions开关阻止几乎所有内容,其中最重要的是ForceOffline开关,但即使关闭所有开关,它仍会通过一些内容,如[object]或[iframe]标记。我知道这是这种情况,因为我实现了OnBeforeNavigate2事件,并且它会触发这些标记中包含的URL,并在本地服务器日志中进行记录。在TEmbeddedWB中设置OfflineMode和ForceOfflineMode对于这些项目无效。
那么我该如何真正阻止所有内容?因此,它需要作为基本HTML开始,其中包括被阻止的外部元素,包括脚本和CSS。有没有一种方法可以在每次下载任何内容时触发事件,以便可以阻止它或通过阻止所有外部下载来避免首先触发此类事件?我需要调整Internet Explorer区域和安全性吗?任何指向正确方向的指针都将有所帮助。
第二项也很棘手,因为我需要检测是否存在问题标记(例如“applet”、“script”、“link”等)。这种检测不需要完美,但必须足够好以涵盖大多数此类标记。我是这样做的:
//----------------------------------------------------------------------
// Check for external content (images, scripts, ActiveX, frames...)
//----------------------------------------------------------------------
try
{
bool HasExternalContent = false;
DelphiInterface<IHTMLDocument2> diDoc; // Smart pointer wrapper - should automatically call release() and do reference counting
diDoc = TEmbeddedWB->Document;
DelphiInterface<IHTMLElementCollection> diColApplets; DelphiInterface<IDispatch> diDispApplets; DelphiInterface<IHTMLObjectElement> diObj;
DelphiInterface<IHTMLElementCollection> diColEmbeds; DelphiInterface<IDispatch> diDispEmbeds;
DelphiInterface<IHTMLFramesCollection2> diColFrames; DelphiInterface<IDispatch> diDispFrames;
DelphiInterface<IHTMLElementCollection> diColImages; DelphiInterface<IDispatch> diDispImages; DelphiInterface<IHTMLImgElement> diImg;
DelphiInterface<IHTMLElementCollection> diColLinks; DelphiInterface<IDispatch> diDispLinks;
DelphiInterface<IHTMLElementCollection> diColPlugins; DelphiInterface<IDispatch> diDispPlugins;
DelphiInterface<IHTMLElementCollection> diColScripts; DelphiInterface<IDispatch> diDispScripts;
DelphiInterface<IHTMLStyleSheetsCollection> diColStyleSheets; DelphiInterface<IDispatch> diDispStyleSheets;
OleCheck(diDoc->Get_applets (diColApplets));
OleCheck(diDoc->Get_embeds (diColEmbeds));
OleCheck(diDoc->Get_frames (diColFrames));
OleCheck(diDoc->Get_images (diColImages));
OleCheck(diDoc->Get_links (diColLinks));
OleCheck(diDoc->Get_plugins (diColPlugins));
OleCheck(diDoc->Get_scripts (diColScripts));
OleCheck(diDoc->Get_styleSheets (diColStyleSheets));
// Scan for applets external links
for (int i = 0; i < diColApplets->length; i++)
{
OleCheck(diColApplets->item(i,i,diDispApplets));
if (diDispApplets != NULL)
{
diDispApplets->QueryInterface(IID_IHTMLObjectElement, (void**)&diObj);
if (diObj != NULL)
{
UnicodeString s1 = Sysutils::Trim(diObj->data),
s2 = Sysutils::Trim(diObj->codeBase),
s3 = Sysutils::Trim(diObj->classid);
if (StartsText("http", s1) || StartsText("http", s2) || StartsText("http", s3))
{
HasExternalContent = true;
break; // At least 1 found, bar will be shown, no further search needed
}
}
}
}
// Scan for images external links
for (int i = 0; i < diColImages->length; i++)
{
OleCheck(diColImages->item(i,i,diDispImages));
if (diDispImages != NULL) // Unnecessary? OleCheck throws exception if this applies?
{
diDispImages->QueryInterface(IID_IHTMLImgElement, (void**)&diImg);
if (diImg != NULL)
{
UnicodeString s1 = Sysutils::Trim(diImg->src);
// Case insensitive check
if (StartsText("http", s1))
{
HasExternalContent = true;
break; // At least 1 found, bar will be shown, no further search needed
}
}
}
}
}
catch (Exception &e)
{
// triggered by OleCheck
ShowMessage(e.Message);
}
有没有更简单的方法来扫描这个问题,或者唯一的方法是使用其他接口函数运行几个循环,例如Get_applets
,Get_embeds
,Get_stylesheets
等类似于上面的代码?到目前为止,我发现我必须调用以下函数来覆盖所有内容:
OleCheck(diDoc->Get_applets (diColApplets));
OleCheck(diDoc->Get_embeds (diColEmbeds));
OleCheck(diDoc->Get_frames (diColFrames));
OleCheck(diDoc->Get_images (diColImages));
OleCheck(diDoc->Get_links (diColLinks));
OleCheck(diDoc->Get_plugins (diColPlugins));
OleCheck(diDoc->Get_scripts (diColScripts));
OleCheck(diDoc->Get_styleSheets (diColStyleSheets));
但如果有更简单的处理方式,我不想实现那么多循环。有吗?
TWebBrowser.Offline
设置为 True 即可;-) - TLama