您可以指定不同的URL。例如,您可以将内容提取到临时文件中并导航到该文件。这不会将您的内容放入受信任的区域,但比about协议获得的互联网区域更好。
如果您不想保存内容,可以先导航到about:blank,然后在{{link1:DocumentComplete}}中,QI文档以获取{{link2:IPersistMoniker
}},并使用基本上模拟url moniker的TInterfacedObject调用Load。
IMoniker.GetDisplayName
的实现需要返回 URL。URL 需要在受信任的区域内。
IMoniker.BindToStorage
的实现需要在 IStream 被请求时返回对 TMemoryStream 的引用。
还有第三种方法,编写一个进程级安全管理器,将您的 URL 放入受信任的区域中。
解决方案是实现自己的Internet安全管理器服务,创建一个实现IInternetSecurityManager
接口的对象(参见MSDN:实现自定义安全管理器)。有五个安全区域:
- 本地:
URLZONE_LOCAL_MACHINE
(0)
- 内部网:
URLZONE_INTRANET
(1)
- 受信任的:
URLZONE_TRUSTED
(2)
- 互联网:
URLZONE_INTERNET
(3)
- 受限制的:
URLZONE_UNTRUSTED
(4)
你真正需要关心的唯一方法是MapUrlToZone
:
TEmbeddedSecurityManager = class(TInterfacedObject, IInternetSecurityManager)
public
function MapUrlToZone(pwszUrl: LPCWSTR; out dwZone: DWORD; dwFlags: DWORD): HResult; virtual; stdcall;
end;
此方法检查Url是否以about:security开头。
about:security_Contoso.exe
如果是这样,则返回该区域应为“本地”:
function TEmbeddedSecurityManager.MapUrlToZone(pwszUrl: LPCWSTR; out dwZone: DWORD; dwFlags: DWORD): HResult;
var
url: UnicodeString;
begin
Result := INET_E_DEFAULT_ACTION;
url := pwszUrl;
if url.StartsWith('about:security') then
begin
dwZone := URLZONE_LOCAL_MACHINE;
Result := S_OK;
end;
end;
每个其他的方法必须返回INET_E_DEFAULT_ACTION
(即不是S_OK也不是E_NOTIMPL),例如:
function TEmbeddedSecurityManager.SetSecuritySite(Site: IInternetSecurityMgrSite): HResult;
begin
Result := INET_E_DEFAULT_ACTION;
end;
当嵌入式WebBrowser调用IServiceProvider.QueryService时,您为其提供此服务。对于Delphi的TEmbeddedWB控件,它在OnQueryService
事件中公开:
function TForm1.EmbeddedWBQueryService(const rsid, iid: TGUID; out Obj: IInterface): HRESULT;
var
sam: IInternetSecurityManager;
begin
Result := E_NOINTERFACE;
if IsEqualGUID(rsid, IInternetSecurityManager) and IsEqualGUID(iid, IInternetSecurityManager) then
begin
sam := TEmbeddedSecurityManager.Create;
Obj := sam;
Result := S_OK;
end;
end;
IStream
中加载页面。 - Ian Boyd