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

Flutter中webview_flutter 4.0.2实现WebView内链接跳转求助

解决webview_flutter 4.0.2中WebView内部链接无法跳转的问题

你的代码缺少对WebView导航请求的处理逻辑,同时JavaScript模式启用时机有误,导致内部链接无法正常跳转。按以下步骤修改即可解决:

1. 配置导航请求回调

在setNavigationDelegate中添加onNavigationRequest回调,明确允许链接的跳转请求:

..setNavigationDelegate(NavigationDelegate(
  onPageFinished: (_) {
    updateHeight();
  },
  onNavigationRequest: (request) {
    // 允许所有链接在WebView内跳转,也可根据URL规则过滤特定链接
    return NavigationDecision.navigate;
  },
))

2. 调整JavaScript模式启用时机

必须在加载HTML之前启用JavaScript模式,否则WebView无法解析页面中的交互逻辑(包括链接跳转):
将await _controller.setJavaScriptMode(JavaScriptMode.unrestricted);移到loadHtmlString执行前。

3. 可选:区分内部/外部链接跳转

如果需要让外部链接跳转到系统浏览器,可修改onNavigationRequest逻辑(需额外引入url_launcher包):

onNavigationRequest: (request) {
  if (request.url.startsWith('http://your-internal-domain') || request.url.startsWith('https://your-internal-domain')) {
    // 内部链接在WebView内跳转
    return NavigationDecision.navigate;
  } else {
    // 外部链接打开系统浏览器
    // await launchUrl(Uri.parse(request.url));
    return NavigationDecision.prevent;
  }
},

修改后的完整代码

import 'dart:io';
import 'dart:ui';
 
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:webview_flutter/webview_flutter.dart';
 
class MyWidget extends StatefulWidget {
  final MyWidgetModel model;
  const MyWidget({Key? key, required this.model}) : super(key: key);
 
  @override
  State<MyWidget> createState() => _MyWidgetState();
}
 
class _MyWidgetState extends State<MyWidget> {
  late final WebViewController _controller;
 
  double webViewHeight = 10;
  bool loading = true;
 
  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted) // 提前启用JavaScript
      ..setNavigationDelegate(NavigationDelegate(
        onPageFinished: (_) {
          updateHeight();
        },
        onNavigationRequest: (request) {
          // 允许所有链接在WebView内跳转
          return NavigationDecision.navigate;
        },
      ));
 
    initWebView();
  }
 
  void initWebView() async {
    String htmlString = '';
 
    final startIndex = widget.model.page?.indexOf('<head>') ?? -1;
    if (startIndex > -1) {
      htmlString = widget.model.page!;
    } else {
      htmlString = '''
      <!DOCTYPE html>
      <head>
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      </head>
      <body>
      ${widget.model.page ?? ''}
      </body>
      </html>
      ''';
    }
    await _controller.loadHtmlString(htmlString);
    _controller.enableZoom(true);
  }
 
  void updateHeight() async {
    final screenHeight = MediaQuery.of(context).size.height;
    final bottomPadding = MediaQueryData.fromWindow(window).padding.bottom;
    final topPadding = MediaQueryData.fromWindow(window).padding.top;
    const appBarHeight = 84;
    final bottomBarPadding = Platform.isIOS ? 70 : 90;
    final minimumHeight = screenHeight -
        bottomBarPadding -
        bottomPadding -
        topPadding -
        appBarHeight;
    webViewHeight = minimumHeight;
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      setState(() {
        loading = false;
      });
    });
  }
 
  @override
  Widget build(BuildContext context) {
    if (widget.model.description == 'web_view') {
      return Container(
        constraints: BoxConstraints(minHeight: 0, maxHeight: webViewHeight),
        child: Stack(
          children: [
            WebViewWidget(
              controller: _controller,
            ),
            if (loading)
              const Positioned.fill(
                  child: CircularProgressIndicator(
              ))
          ],
        ),
      );
    }
    // 补充默认返回值,避免编译错误
    return const SizedBox.shrink();
  }
}

额外说明

  • 确保HTML中的链接为标准<a href="xxx">格式,无自定义JS阻止跳转的逻辑
  • 页面内锚点跳转(如#section)无需额外配置,WebView会自动处理

内容的提问来源于stack exchange,提问作者Tux Ficus Mercury

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 07:20:18