Web 浏览器控件和嵌入标记

本文关键字:浏览器 控件 Web | 更新日期: 2023-09-27 18:36:28

我相信我遇到了与在 C# 2008 WinForms 应用程序中将嵌入标记与 WebBrowser 控件一起使用相关的安全问题。

这是我的代码:

private void button2_Click(object sender, EventArgs e)
{
    webBrowser1.Navigate("C:/page1.html");
}
private void button1_Click(object sender, EventArgs e)
{
    webBrowser1.Navigate("about:blank");
    Thread.Sleep(1000);
    webBrowser1.Document.Write("<html><body><p>Hello</p><embed src='C:/test.wmv' /></body></html>");
}

这是第1.html页的内容:

<html><body><p>Hello</p><embed src='C:/test.wmv' /></body></html>

按钮 1 生成单词"Hello"。Button2 生成单词"Hello",其下方有一个嵌入式电影播放器。

当我查看两个页面的源代码时,我注意到它们是相同的,除了源文件的名称。

这让我相信这与我的 IE 安全设置有关,但我注意到我为嵌入内容设置了完全权限。也许控件无法将页面的源识别为正确,因此不允许使用嵌入标记。

如何以编程方式克服此问题?我想避免将我的页面写入文件,并不惜一切代价导航到该文件。关于如何欺骗浏览器控件正常工作的任何建议?

第一编辑:

根据这篇文章 Webbrowser 导航嵌入式资源,这将起作用,但我 (JT) 尝试过,但它没有:

System.IO.Stream stream = this.GetType().Assembly.GetManifestResourceStream("WindowsFormsApplication1.Properties.test.html");
webBrowser1.DocumentStream = stream;

重现问题时的奇怪行为:

webBrowser1.Navigate("about:blank");
do
{
Thread.Sleep(100);
} while (webBrowser1.IsBusy == true);
//Method 1. Doesn't work
string htmlString1 = File.ReadAllText("C:/page1.html");
webBrowser1.Document.Write(htmlString1);
//Method 2. Doesn't work
string htmlString2 = "<html><body><p>Hello</p><embed src='C:/test.wmv' /></body></html>";
webBrowser1.Document.Write(htmlString2);
//Method 3. DOES WORK
webBrowser1.Document.Write("<html><body><p>Hello</p><embed src='C:/test.wmv' /></body></html>");

编辑 2

下面是一个使用 JavaScript 创建的页面示例,没有真正的源文件,它确实在 IE 中显示嵌入式播放器:

<html><head>
<script language="JavaScript">
function go()
{
test1 = window.open("","","menubar=0,status=0,toolbar=0");
test1.document.writeln("<html><body><p>Hello</p><embed src='test.wmv' /></body></html>");
}
</script>
</head><body><h1 onclick="go()">click</h1></body></html>

这里唯一的区别是IE认为HTML的来源是一个文件,尽管它是由"writeln"创建的。

虽然人们普遍认为IE不支持该标签,但它确实支持,并且有很多例子证明了这一点。在IE中尝试使用IE jsfiddle.net 会让嵌入式播放器大喊大叫,而在FF中则不会

编辑 3

此问题与跨域安全性有关。更新版本的 IE 不仅拒绝允许在页面域存在后对其进行任何更改,而且 WebBrowser 控件也不允许您将文本写入已包含文本的文档。只有对 Document.Write 的第一次调用才能执行任何操作。不仅没有明显的方法来强制页面的域,也没有办法将任何新内容写入具有设置域的页面,因为"openNew"(这是进行任何写入所必需的)打开 about:blank 并默认为空域,如果尝试设置或获取会导致异常。

编辑 4

问题在于跨域安全恶作剧。请参阅此IE8决定无法写入Document.Domain。即使它是可写的,你显然永远无法在协议之间进行通信。因此,"file://"协议和"关于"协议无法通信,或者标签相互指向。以下是绊脚石:

  • 浏览器控件使用的 IE 版本无法执行任何操作Document.Domain,甚至没有JavaScript。
  • 您无法读取 about:blank 的域。
  • 您无法使用正确的域加载页面,并期望使用Document.Write 将 HTML 写入其中,因为您被迫调用Document.OpenNew 在使用 Document.Write 之前。
  • 不能使用 WebBrowser.DocumentText = 修改文档文本。文档文本 =任何内容,因为每个导航只能设置一次文档文本。这就像其他一些安全的事情

总之,只要说您对 WebBrowser 控件的安全性没有任何额外的控制就足够了,甚至可能比某些 JavaScript 生成的页面还要少(因为这些页面共享启动脚本的域)。

感谢您对我

努力的投票/支持,但每次我想更改浏览器控件中的内容时,看起来我都会放弃并编写一个页面到文件。呸。

Web 浏览器控件和嵌入标记

问题在于跨域安全恶作剧。请参阅此IE8决定无法写入Document.Domain。即使它是可写的,你显然永远无法在协议之间进行通信。因此,"file://"协议和"关于"协议无法通信,或者标签相互指向。以下是绊脚石:

  • 浏览器控件使用的 IE 版本无法执行任何操作Document.Domain,甚至没有JavaScript。
  • 您无法读取 about:blank 的域。
  • 您无法使用正确的域加载页面,并期望使用Document.Write 将 HTML 写入其中,因为您被迫调用Document.OpenNew 在使用 Document.Write 之前。
  • 不能使用 WebBrowser.DocumentText = 修改文档文本。文档文本 =任何内容,因为每个导航只能设置一次文档文本。这就像其他一些安全的事情

总之,只要说您对 WebBrowser 控件的安全性没有任何额外的控制就足够了,甚至可能比某些 JavaScript 生成的页面还要少(因为这些页面共享启动脚本的域)。

感谢您对我

努力的投票/支持,但每次我想更改浏览器控件中的内容时,看起来我都会放弃并编写一个页面到文件。呸。

这就是为什么:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd562847(v=vs.85).aspx

前面的示例适用于 Firefox,但不适用于 Internet Explorer。 将 Player 控件嵌入到可由 Internet Explorer,您必须创建一个具有 classid 属性设置为Windows 媒体播放器的类 ID 控制。 以下示例演示如何嵌入Windows 媒体播放器 在网页中控件,该控件可由两个互联网正确显示 资源管理器和火狐浏览器。页面上的脚本检测浏览器类型和 生成相应的对象标记。

为了您的方便,这里是:

private void button3_Click(object sender, EventArgs e)
{
    webBrowser1.Navigate("about:blank");
    do
    {
        Thread.Sleep(100);
    } while (webBrowser1.IsBusy == true);
    string htmlString1 = File.ReadAllText("C:/test.html");
    webBrowser1.Document.Write(htmlString1);
    return;
}

测试内容.html:

<OBJECT id="VIDEO" width="320" height="240" 
    style="position:absolute; left:0;top:0;"
    CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6"
    type="application/x-oleobject">
    <PARAM NAME="URL" VALUE="c:'test.wmv">
    <PARAM NAME="SendPlayStateChangeEvents" VALUE="True">
    <PARAM NAME="AutoStart" VALUE="True">
    <PARAM name="uiMode" value="none">
    <PARAM name="PlayCount" value="9999">
</OBJECT>

@GorchestopherH听到结果真是太可惜了。您可能希望将第 4 次编辑作为答案 - 完全失去 50pts 赏金将是一种耻辱。

另一个

解决方案是另一个 Web 浏览器控件:http://code.google.com/p/geckofx/

使用 GeckoFX 在 C# 中嵌入 Firefox Brower