首页 文章

WebBrowser控件和嵌入标签

提问于
浏览
12

我相信我遇到了与在我的C#2008 WinForms应用程序中使用带有WebBrowser控件的embed标签相关的安全问题 .

这是我的代码:

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>");
}

这是page1.html的内容:

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

Button1生成单词“Hello” . Button2生成单词“Hello”,其下方嵌入了一个电影播放器 .

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

这让我相信它与我的IE安全设置有关,但我注意到我为嵌入式内容设置了完整的权限 . 也许控件不能正确识别页面的来源,因此不允许使用嵌入标签 .

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

1st Editor:

根据这篇文章Webbrowser Navigate Embedded Resource这将有效,但我(JT)尝试过它并没有:

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

Odd behavior while reproducing problem:

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>");

Edit 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的jsfiddle.net上尝试使用IE会产生嵌入式播放器,而在FF中却不会 .

Edit 3

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

Edit 4

问题在于跨域安全诡计 . 请参阅THIS IE8决定Document.Domain可以't be written to. Even if it were writable, you can apparently never communicate between protocols. So the 2488715 protocol, and the 2488716 protocol can't进行通信,或者让标签彼此指向 . 以下是绊脚石:

  • 浏览器控件使用的IE版本无法对Document.Domain执行任何操作,即使使用JavaScript也无法执行任何操作 .

  • 您无法读取about:blank的域名 .

  • 您无法加载具有正确域的页面,并且期望使用Document.Write将HTML写入其中,因为在使用Document.Write之前您必须调用Document.OpenNew .

  • 您无法使用WebBrowser.DocumentText = any修改DocumentText,因为每个导航只能设置一次DocumentText . 这就像其他一些安全事情 .

总而言之,您可以通过WebBrowser控件对安全性没有任何额外的控制,甚至可能比使用一些JavaScript生成的页面更少(因为这些页面共享启动脚本的域) .

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

3 回答

  • 2

    问题在于跨域安全诡计 . 请参阅THIS IE8决定Document.Domain可以't be written to. Even if it were writable, you can apparently never communicate between protocols. So the 2488719 protocol, and the 2488720 protocol can't进行通信,或者让标签指向彼此 . 以下是绊脚石:

    • 浏览器控件使用的IE版本无法对Document.Domain执行任何操作,即使使用JavaScript也无法执行任何操作 .

    • 您无法读取about:blank的域名 .

    • 您无法加载具有正确域的页面,并且期望使用Document.Write将HTML写入其中,因为在使用Document.Write之前您必须调用Document.OpenNew .

    • 您无法使用WebBrowser.DocumentText = any修改DocumentText,因为每个导航只能设置一次DocumentText . 这就像其他一些安全事情 .

    总而言之,您可以通过WebBrowser控件对安全性没有任何额外的控制,甚至可能比使用一些JavaScript生成的页面更少(因为这些页面共享启动脚本的域) .

    感谢我的努力中的投票/支持,但看起来每次我想改变其中的内容时我都会放弃并写一个页面来存档浏览器控件 . 呸 .

  • 1

    这就是为什么:

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

    前面的示例适用于Firefox,但不适用于Internet Explorer . 若要将Player控件嵌入可由Internet Explorer显示的网页中,必须创建一个OBID元素,该元素的classid属性设置为Windows Media Player控件的类ID . 以下示例说明如何将Windows Media Player控件嵌入到可由Internet Explorer和Firefox正确显示的网页中 . 页面上的脚本检测浏览器类型并生成相应的OBJECT标记 .

    为了您的方便,这里是:

    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;
    }
    

    Test.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>
    
  • 1

    @GorchestopherH听到结果很遗憾 . 你可能希望将第4次编辑作为答案 - 完全放弃50pts赏金是一种耻辱 .

    另一个解决方案是另一个webbrowser控件:http://code.google.com/p/geckofx/

    Embeding Firefox Brower In C# Using GeckoFX

相关问题