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
相关产品推荐
相关产品推荐

