flutter webview unable to go back when url is redirect

1k Views Asked by At

I am building a flutter application. Use of this application is show the web pages in webview. In this application have one button. While clicking the button it needs to open webview and load the url. But some web url have redirection. So in the application we can't go back. For example one url. http://sample.com/firstpage.html. When entering the url on normal browser. It will automatically redirect to http://sample.com/secondpage.html . In the browser when click back button from secondpage.html. It will not go back to firstpage.html. But in my webview it is going on loop. when i loading http://sample.com/firstpage.html in web view. First it will load firstpage.html and after that it is automatically redirecting to secondpage.html. After that when i clicking back button. It is again loading firstpagehtml and automatically loading again secondpage.html. How to go back without entering to firstpage.html. It is working fine in normal browser but it is not working web view. How to resolve it?


        import 'package:flutter/material.dart';
        import 'package:webview_flutter/webview_flutter.dart';


        void main() => runApp(const MaterialApp(home: WebViewExample()));

        class WebViewExample extends StatefulWidget {
          const WebViewExample({super.key});

          @override
          State<WebViewExample> createState() => _WebViewExampleState();
        }

        class _WebViewExampleState extends State<WebViewExample> {
          @override
          Widget build(BuildContext context) {
            return Scaffold(
              backgroundColor: Colors.green,

              body: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(onPressed: (){
                    Navigator.push(context, MaterialPageRoute(builder: (context){ return WebViewExample1();}));
                  }, child: Text("open web view"))
                ],
              ),
            );
          }
        }


        class WebViewExample1 extends StatefulWidget {
          const WebViewExample1({super.key});

          @override
          State<WebViewExample1> createState() => _WebViewExample1State();
        }

        class _WebViewExample1State extends State<WebViewExample1> {
          late final WebViewController _controller;

          @override
          void initState() {
            super.initState();


          _loadPageFn2();
          }

          void _loadPageFn2(){
            final WebViewController controller =WebViewController();

            controller
              ..setJavaScriptMode(JavaScriptMode.unrestricted)
              ..setNavigationDelegate(
                NavigationDelegate(
                  onProgress: (int progress) {
                    debugPrint('WebView is loading (progress : $progress%)');
                  },
                  onPageStarted: (String url) {
                    debugPrint('Page started loading: $url');
                  },
                  onPageFinished: (String url) {
                    debugPrint('Page finished loading: $url');
                  },
                  onNavigationRequest: (NavigationRequest request) {
                    if (request.url.startsWith('https://www.youtube.com/')) {
                      debugPrint('blocking navigation to ${request.url}');
                      return NavigationDecision.prevent;
                    }
                    debugPrint('allowing navigation to ${request.url}');
                    return NavigationDecision.navigate;
                  },
                  onUrlChange: (UrlChange change) {
                    debugPrint('url change to ${change.url}');
                  },
                ),
              )

              ..setNavigationDelegate(
                NavigationDelegate(
                  onProgress: (int progress) {
                    debugPrint('WebView is loading (progress : $progress%)');
                  },
                  onPageStarted: (String url) {
                    debugPrint('Page started loading: $url');
                  },
                  onPageFinished: (String url) {
                    debugPrint('Page finished loading: $url');
                  },
                  onWebResourceError: (WebResourceError error) {
                    debugPrint('''
        Page resource error:
          code: ${error.errorCode}
          description: ${error.description}
          errorType: ${error.errorType}
          isForMainFrame: ${error.isForMainFrame}
                  ''');
                  },
                  onNavigationRequest: (NavigationRequest request)async {

                     debugPrint('allowing navigation to ${request.url}');
                     return NavigationDecision.navigate;

                  },
                  onUrlChange: (UrlChange change) {
                    debugPrint('url change to ${change.url}');
                  },
                ),
              )

              ..loadRequest(Uri.parse('http://sample.com/firstpage.html'));

            _controller = controller;

          }



          @override
          Widget build(BuildContext context) {
            return Scaffold(
              backgroundColor: Colors.green,

              body: WillPopScope(
                onWillPop: ()async{
                  
        if(await _controller.canGoBack()){
            _controller.goBack();
            return false;
          } else{
            return true;
          }

                },
                child: WebViewWidget(controller: _controller),
              ),
            );
          }

        }





1

There are 1 best solutions below

0
Timothy Yandl On

Not a satisfying answer: if you do not implement the onNavigationRequest callback at all, the back behavior should be as you expect it to be.

I think this is a bug in the webview library. I've created this bug for it: https://github.com/flutter/flutter/issues/137737