How can I prevent a Flutter WebView from navigating to external URLs or opening other pages?


I'm building a vidsrc.to client to watch movies on my Android phone, using webview_flutter 4.x, I want to load a specific embedded video page inside a WebView, but I need to prevent the webpage from navigating the WebView to other domains or opening external pages.

My current setup is roughly:


  controller = WebViewController()
    ..setJavaScriptMode(JavaScriptMode.unrestricted)
    ..loadRequest(Uri.parse('https://vidsrc.to/embed/movie/tt17048515'));
}

The page itself contains iframes and JavaScript that load resources from other domains. For example, the initial page can load content from vsembed.ru and other third-party domains.

I tried using NavigationDelegate:

..setNavigationDelegate(
  NavigationDelegate(
    onNavigationRequest: (request) {
      final uri = Uri.tryParse(request.url);

      if (uri == null) {
        return NavigationDecision.prevent;
      }

      const allowedHosts = {'vidsrc.to','vsembed.ru',};

      return allowedHosts.contains(uri.host)
          ? NavigationDecision.navigate
          : NavigationDecision.prevent;
    },
  ),
)

This works for top-level navigation, but it doesn't seem to prevent JavaScript/iframes inside the page from loading resources or attempting to access other domains

Minimal reproducible example:

import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: WebViewPage(), ); } } class WebViewPage extends StatefulWidget { const WebViewPage({super.key}); @override State<WebViewPage> createState() => _WebViewPageState(); } class _WebViewPageState extends State<WebViewPage> { late final WebViewController controller; @override void initState() { super.initState(); controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate( NavigationDelegate( onNavigationRequest: (request) { final uri = Uri.tryParse(request.url); if (uri == null) { return NavigationDecision.prevent; } const allowedHosts = { 'example.com', 'allowed.example.com', }; if (allowedHosts.contains(uri.host)) { return NavigationDecision.navigate; } return NavigationDecision.prevent; }, ), ) ..loadRequest( Uri.parse('https://example.com'), ); } @override Widget build(BuildContext context) { return Scaffold( body: WebViewWidget( controller: controller, ), ); } }
1
Aug 17 at 3:01 AM
User AvatarAugusto Massotti
#android#flutter#iframe#mobile#webview

No answer found for this question yet.