You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI Blazor中如何将WebView作为组件嵌入页面?

解决方案:MAUI Blazor中嵌入类浏览器组件展示互联网内容

一、在Blazor组件中调用原生WebView(纠正BlazorWebView的误用)

你混淆了BlazorWebView的用途——它是用来在MAUI中承载Blazor内容的,要显示外部网页,应该用MAUI的原生WebView组件,通过自定义ContentView实现Blazor与XAML组件的交互:

1. 创建包含原生WebView的XAML ContentView

新建BrowserView.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="YourAppNamespace.BrowserView">
    <WebView x:Name="NativeWebView" 
             HorizontalOptions="FillAndExpand"
             VerticalOptions="FillAndExpand" />
</ContentView>

对应的BrowserView.xaml.cs:

namespace YourAppNamespace;

public partial class BrowserView : ContentView
{
    // 定义可绑定的Source属性,供Blazor组件传参
    public static readonly BindableProperty SourceProperty =
        BindableProperty.Create(nameof(Source), typeof(string), typeof(BrowserView), propertyChanged: OnSourceUpdated);

    public string Source
    {
        get => (string)GetValue(SourceProperty);
        set => SetValue(SourceProperty, value);
    }

    private static void OnSourceUpdated(BindableObject bindable, object oldVal, object newVal)
    {
        if (bindable is BrowserView view && newVal is string url)
        {
            view.NativeWebView.Source = new UrlWebViewSource { Url = url };
        }
    }

    public BrowserView() => InitializeComponent();
}

2. 在Blazor组件中引用该ContentView

首先在_Imports.razor添加命名空间:

@using YourAppNamespace

然后在Blazor页面/组件中直接使用:

<h3>嵌入式网页浏览器</h3>
<BrowserView Source="https://example.com" style="width:100%;height:600px;" />

二、解决WebView内容拦截问题

很多网站会限制在WebView中加载,通过配置各平台的WebView参数可以缓解:

Android平台配置

在Platforms/Android/MainActivity.cs的OnCreate方法中添加全局WebView配置:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("CustomWebViewConfig", (handler, view) =>
    {
        if (handler.PlatformView is Android.Webkit.WebView webView)
        {
            // 启用JS和DOM存储
            webView.Settings.JavaScriptEnabled = true;
            webView.Settings.DomStorageEnabled = true;
            // 允许跨域资源访问(按需开启)
            webView.Settings.AllowUniversalAccessFromFileURLs = true;
            // 设置自定义WebViewClient,拦截跳转并允许加载
            webView.SetWebViewClient(new CustomWebViewClient());
        }
    });
}

// 自定义WebViewClient处理跳转和SSL错误
public class CustomWebViewClient : Android.Webkit.WebViewClient
{
    public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
    {
        // 强制在当前WebView加载所有链接,不跳转系统浏览器
        view.LoadUrl(request.Url.ToString());
        return true;
    }

    public override void OnReceivedSslError(Android.Webkit.WebView view, SslErrorHandler handler, SslError error)
    {
        // 忽略SSL错误(仅测试环境使用,生产环境需谨慎)
        handler.Proceed();
    }
}

iOS平台配置

在Platforms/iOS/AppDelegate.cs的FinishedLaunching方法中添加:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("CustomWebViewConfig", (handler, view) =>
    {
        if (handler.PlatformView is WKWebView wkWebView)
        {
            wkWebView.Configuration.Preferences.JavaScriptEnabled = true;
            wkWebView.Configuration.AllowsInlineMediaPlayback = true;
            // 允许文件跨域访问
            wkWebView.Configuration.Preferences.SetValueForKey(NSObject.FromObject(true), new NSString("allowFileAccessFromFileURLs"));
            wkWebView.NavigationDelegate = new CustomNavigationDelegate();
        }
    });

    return base.FinishedLaunching(app, options);
}

// 自定义导航代理允许所有请求
public class CustomNavigationDelegate : WKNavigationDelegate
{
    public override void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
    {
        decisionHandler(WKNavigationActionPolicy.Allow);
    }
}

Windows平台配置

在Platforms/Windows/App.xaml.cs的OnLaunched方法中添加:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    base.OnLaunched(args);

    Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("CustomWebViewConfig", (handler, view) =>
    {
        if (handler.PlatformView is Microsoft.UI.Xaml.Controls.WebView2 webView)
        {
            webView.CoreWebView2InitializationCompleted += (s, e) =>
            {
                if (e.IsSuccess)
                {
                    webView.CoreWebView2.Settings.JavaScriptEnabled = true;
                    webView.CoreWebView2.Settings.AllowUniversalAccessFromFileUrls = true;
                }
            };
        }
    });
}

三、进阶方案:调用系统浏览器获取完整体验

如果需要书签、下载、完整的浏览器安全特性等,可以通过JS互操作调用MAUI的系统浏览器API:

1. Blazor组件代码

<button @onclick="OpenInSystemBrowser" class="btn btn-primary">在系统浏览器打开</button>

@code {
    [Inject]
    public IJSRuntime JsRuntime { get; set; }

    private async Task OpenInSystemBrowser()
    {
        await JsRuntime.InvokeVoidAsync("openSystemBrowser", "https://example.com");
    }
}

2. 前端JS代码(wwwroot/js/app.js)

window.openSystemBrowser = async (url) => {
    await DotNet.invokeMethodAsync('YourAppNamespace', 'LaunchSystemBrowser', url);
};

3. MAUI后端代码

namespace YourAppNamespace;

public static class BrowserLauncher
{
    [JSInvokable]
    public static async Task LaunchSystemBrowser(string url)
    {
        await Browser.Default.OpenAsync(url, BrowserLaunchMode.SystemPreferred);
    }
}

内容的提问来源于stack exchange,提问作者Bisjob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:24:30