我相信我遇到了与在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安全设置有关,但我注意到我为嵌入式内容设置了完整的权限。控件可能无法识别页面的来源,因此不允许使用嵌入标记。
如何以编程方式克服此问题?我想避免将我的页面写入文件,并不惜一切代价导航到该文件。有关如何欺骗浏览器控件正常工作的任何建议吗?
第一编辑:
根据这篇文章Webbrowser Navigate Embedded Resource,这将有效,但是我(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浏览器中使用IE浏览器会使用嵌入式播放器,而在FF 中则不会。
编辑3
此问题与跨域安全性有关。不仅较新版本的IE拒绝允许对页面域进行任何更改,WebBrowser控件不允许您将文本写入已包含文本的文档。只有第一次调用Document.Write才能做任何事情。不仅没有明显的方法来强制页面域,也没有办法用设置域的页面写任何新内容,因为“openNew”是执行任何写入所必需的,打开:空白并默认为空域,如果尝试设置或获取,则会导致异常。
编辑4
问题在于跨域安全诡计。请参阅THIS IE8决定无法写入Document.Domain。即使它是可写的,你显然也不会在协议之间进行通信。因此,“file://”协议和“about”协议无法通信,或者标签彼此指向。以下是绊脚石:
总之,只需说您对WebBrowser控件的安全性没有任何额外控制就足够了,甚至可能比使用一些JavaScript生成的页面更少(因为这些页面共享启动脚本的域)
感谢我的努力中的投票/支持,但看起来每次我想要更改浏览器控件中的内容时,我都会放弃并编写一个页面来存档。呸。
答案 0 :(得分:2)
问题在于跨域安全诡计。请参阅THIS IE8决定无法写入Document.Domain。即使它是可写的,你显然也不会在协议之间进行通信。因此,“file://”协议和“about”协议无法通信,或者标签彼此指向。以下是绊脚石:
总之,只需说您对WebBrowser控件的安全性没有任何额外控制就足够了,甚至可能比使用一些JavaScript生成的页面更少(因为这些页面共享启动脚本的域)
感谢我的努力中的投票/支持,但看起来每次我想要更改浏览器控件中的内容时,我都会放弃并编写一个页面来存档。呸。
答案 1 :(得分:1)
这就是原因:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd562847(v=vs.85).aspx
前面的示例适用于Firefox,但不适用于Internet Explorer。 将Player控件嵌入可以显示的网页中 在Internet Explorer中,您必须创建一个具有的OBJECT元素 classid属性设置为Windows Media Player的类ID 控制。 以下示例显示如何嵌入Windows Media Player 控制网页,可以通过互联网正确显示 资源管理器和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>
答案 2 :(得分:1)
@GorchestopherH听到结果很遗憾。您可能希望将第4次编辑作为答案 - 完全放弃50pts赏金是一种耻辱。
另一个解决方案是另一个web浏览器控件:http://code.google.com/p/geckofx/