WebBrowser控件在一个应用程序中会显示警告信息,但在另一个应用程序中却没有显示

前端开发 2026-07-09

我有一个WPF视图/视图模型,在两个独立的.NET 10.0应用程序中使用。视图的一小段区域通过WebBrowser控件显示一个动画GIF,该GIF会加载一个本地的小HTML文件,HTML文件又引用一个本地的小GIF文件。

在第一个应用中,动画GIF能正常显示,但在第二个应用中,虽然GIF会显示并动画,但也会出现一个恼人的警告横幅。再说一次,这是完全相同的视图和视图模型、相同的XAML、相同的C#、相同的HTML文件、以及相同的GIF。只是运行在两个不同的应用程序中。

有人能告诉我应该在第二个应用中做出什么改动来避免横幅出现吗?我猜肯定存在某种全局设置,在第一个应用中设置了而在第二个没有设置……

以下是在第一个应用中横幅的样子。

在此处输入图片描述

在第二个应用中的横幅如下所示

在此处输入图片描述

以下是包含控件的XAML文件中对应的那一部分

<Grid >
    <WebBrowser x:Name="Browser" Grid.Column="1" IsHitTestVisible="False"
        MinHeight="300" 
        MinWidth="100"/>
</Grid>

以下是将浏览器导航到HTML文件的后台代码

private void CalibrateViewPanel_Loaded(object sender, RoutedEventArgs e)
{
    try
    {
        if (DataContext is not CalibrateVm vm)
            return;

        Browser.Navigate(vm.CurrentUiGuideUri!);
    }
    catch (Exception ex)
    {

        Log.Error(ex);
    }
}

以及被加载的HTML文件

<!DOCTYPE html>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body style="background-color: #E8E8ED; overflow: hidden;"
      oncontextmenu="return false;"
      scroll="no">
    <img max-height="100%"
         width="auto"
         src="modulus-straight-flat.gif" />
</body>
</html>

现在我浏览了一个类似问题的答案的链接,里面提到了名为「Mark of the Web」的信息,用来据说可以解决这类问题。我尝试使用它,在DOCTYPE行之后插入如下注释

<!-- saved from url=(0016)https://localhost -->

但似乎没有效果。即使有效,也无法解释为什么在一个应用中需要它,在另一个应用中却不需要

解决方案

我认为错误与底层的Internet Explorer有关,因为它会将你的HTML中的 oncontextmenu="return false" JavaScript识别为活动内容,因此被视为可疑。这是一个安全特性。

Internet Explorer使用遗留的本地计算机区域概念来对待本地文件资源的更高风险性。

你已经将 WebBrowser.IsHitTestVisible 设置为 false,因此应当可以安全地移除脚本部分(本质上是事件处理程序)。这可能已经解决了你的问题,因为 WebBrowser 控件本身将会忽略鼠标事件。

我不会为公用应用程序禁用“活动内容”安全特性。即使应用程序只加载本地HTML,该HTML也可能成为攻击面,如果文档中的文件、生成的标记、资源路径,或插入到文档中的任何数据被攻击者修改或影响。也就是说,本地源并不等于安全。

在你的情形中,HTML的唯一目的只是加载GIF,你可以完全移除HTML,通过URI导航到GIF资源。这之所以可行,是因为浏览器能够正确处理某些资源。例如,它们可以在不加载显式HTML文档的情况下渲染视频与图像(包括GIF)或播放音频文件:

MainWindow.xaml

<Window x:Class="Wpf.Net.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpf.Net"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <WebBrowser Name="WebBrowser"
                    IsHitTestVisible="False" />
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        // Directly navigate to the GIF resource without a wrapping HTML document.
        // The browser can handle specific resources 
        // like images, gifs, video, audio, json etc. properly.
        // This example navigates to a remote GIF resource hosted by Giphy.
        var gifUri = new Uri("https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExN2Y5ODQxZzlvcXl6cXI2OXc3MGF3d3JhazVlbDJoOWx4ZDU5NzN0NCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/FnXgJ5KG1DqhzD0dF6/giphy.gif");
        WebBrowser.Navigate(gifUri);
    }
}

注:WebBrowser 是一个过时的API,我不再推荐使用。它使用的是相当过时的Internet Explorer引擎,本身也已经过时。

考虑 WebView2 作为替代(WebView2 API概览)。这是官方的.NET,但你可能需要通过NuGet导入 Microsoft.Web.WebView2(不要把它和错误的 Microsoft.AspNetCore.Components.WebView.Wpf 混淆,后者是用于Blazor Hybrid/WPF应用并提供 BlazorWebView)。

WebView2 使用现代Chromium作为浏览器引擎(包括V8作为JavaScript引擎),使用起来同样简单,并且在不需要移除活动内容的情况下也能优雅地处理你的场景:

MainWindow.xaml

<Window x:Class="Wpf.Net.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpf.Net"
        xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <wv2:WebView2 Name="WebBrowser"
                      IsHitTestVisible="False" />
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        // Local or remote resource (URL or file)
        var gifUri = new Uri("https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExN2Y5ODQxZzlvcXl6cXI2OXc3MGF3d3JhazVlbDJoOWx4ZDU5NzN0NCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/FnXgJ5KG1DqhzD0dF6/giphy.gif");

        // To render an HTML string instead, use:
        // WebBrowser.NavigateToString(html);
        WebBrowser.Source = gifUri;
    }
}

小小免责声明:
当然,移除JavaScript只是这里的一个解决方案,因为HTML非常简单,只是包裹一个GIF。

如果你实际需要托管一个真正的HTML/JavaScript文档,通常应避免从本地计算机区域加载活动JavaScript(例如本地文件)。
相反,请从一个合适的HTTP/HTTPS源提供内容(例如在本地使用一个小型Python Web服务器或XAMPP)。

或者使用 WebBrowser.NavigateToString 来生成包含活动内容的简单HTML,例如:

// This will mitigate the warning since you avoid the Local Machine Zone of the IE
string htmlContent = await File.ReadAllTextAsync(gifFileUri.LocalPath);
LegacyWebBrowser.NavigateToString(htmlContent);

或者更推荐使用 WebView2 来处理现代HTML/JavaScript内容,因为它使用现代且快速的V8引擎。请参考上面的示例,了解如何在一个基础用例中使用WebView2。
对于简单的本地HTML/JavaScript,WebView2往往可以直接加载文件,而不会出现IE本地计算机区域警告。对于更复杂的本地Web应用,WebView2的虚拟主机名映射通常比托管本地服务器更好,因为它为本地文件提供了类似HTTP/HTTPS的来源,而无需XAMPP或自定义回送服务器。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章