🌐

【Flutter】WebViewで特定のページにアクセス時に強制リダイレクトする方法

に公開

はじめに

こんにちは。ぽぽらす(@popo_lus)と申します。

FlutterでWebViewを用いたアプリを開発している際、「あるページにアクセスした際に、強制的に他のページにリダイレクトさせる」という処理をしたいことがありました。
同じ悩みをお持ちの方は、この記事を参考にしてみて下さい。

なお、本記事ではFlutterで代表的なWebViewパッケージである「webview_flutter」と「flutter_inappwebview」の二種類での実装方法について説明します。

前提条件

  • Flutter 3.27.0
  • Dart 3.6.0
  • WebViewパッケージ
    • webview_flutter 4.11.0
    • flutter_inappwebview 6.1.5
  • 実行環境 iOS 18.4.1

やりたいことは、「あるページにアクセスした際に、強制的に他のページにリダイレクトさせる」です。
本記事では、例として「Youtubeにアクセスした際に、強制的にニコニコ動画のトップページに遷移させる」という処理を実装していこうと思います。

webview_flutterでの実装方法

以下が、webview_flutterでの実装方法になります。

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

class WebViewFlutterPage extends StatelessWidget {
  const WebViewFlutterPage({super.key});

  final String initialUrl = "https://google.com"; // 初期ロードするURL
  final String targetUrl = "https://www.youtube.com"; // リダイレクト対象のURL
  final String redirectUrl = "https://www.nicovideo.jp"; // リダイレクト先のURL

  
  Widget build(BuildContext context) {
    final controller = WebViewController();
    controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageStarted: (String url) {
            if (url.startsWith(targetUrl)) {
              controller.loadRequest(
                Uri.parse(redirectUrl),
              );
            }
          },
        ),
      )
      ..loadRequest(Uri.parse(initialUrl));

    return Scaffold(
      appBar: AppBar(),
      body: WebViewWidget(
        controller: controller,
      ),
    );
  }
}

このコードのポイントは、NavigationDelegate内のonPageStartedです。
「アクセスしようとしているURLがhttps://youtube.comから始まるならば、https://nicovideo.jpを読み込む」というコードを実装しています。

ページ遷移の条件を変えたい(例えば複数ページをリダイレクト対象に設定したいなど)ときは、ifの条件を変更すればいいですね。

flutter_inappwebviewでの実装方法

以下が、flutter_inappwebviewでの実装方法となります。

inappwebview_page.dart
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class InAppWebViewPage extends StatelessWidget {
  const InAppWebViewPage({super.key});

  final String initialUrl = "https://google.com"; // 初期ロードするURL
  final String targetUrl = "https://www.youtube.com"; // リダイレクト対象のURL
  final String redirectUrl = "https://www.nicovideo.jp"; // リダイレクト先のURL

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: InAppWebView(
        initialUrlRequest: URLRequest(
          url: WebUri(initialUrl),
        ),
        onLoadStop: (controller, url) async {
          if (url == null) return;
          if (url.toString().startsWith(targetUrl)) {
            await controller.loadUrl(
              urlRequest: URLRequest(
                url: WebUri(redirectUrl),
              ),
            );
          }
        },
      ),
    );
  }
}

このコードのポイントは、InAppWebView内のonLoadStopです。
「ロードが終わったURLがhttps://youtube.comから始まるならば、https://nicovideo.jpを読み込む」というコードを実装しています。
(onLoadStart等を用いるとなぜか安定性が著しく低下するため、今回はonLoadStopを使用しています。)

こちらも、先と同様にページ遷移の条件を変えたい(例えば複数ページをリダイレクト対象に設定したいなど)ときは、ifの条件を変更すればいいですね。

まとめ

FlutterのWebViewでは、特定ページにアクセスしようとした際に強制リダイレクトをすることが出来る。
アプリ内ブラウザとは違い、表示するページのコントロールがしやすいのがWebViewの利点ですね。

ぽちぽちのつどい

Discussion