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

webview_flutter Android端无法通过JS navigator.clipboard.writeText复制文本

Android Flutter WebView 剪贴板复制权限问题解决方案

问题背景

在Android设备上使用Flutter的webview_flutter组件加载含JS剪贴板复制功能的页面时,点击复制按钮会触发NotAllowedError: Write permission denied错误,iOS端无此问题。官方明确表示不会修复该问题,建议通过JavaScript Channel结合Flutter原生剪贴板API实现。

可行解决方案

通过桥接Web页面的JS逻辑与Flutter原生剪贴板功能,绕过WebView的JS权限限制。以下是完整可运行的实现代码:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: WebView(
          initialUrl: "https://www.w3schools.com/howto/howto_js_copy_clipboard.asp",
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (controller) {
            _webViewController = controller;
            // 注册JavaScript Channel,用于Web与Flutter的通信
            _webViewController.addJavaScriptChannel(
              'FlutterClipboard',
              onMessageReceived: (message) async {
                // 接收Web页面传递的文本,调用Flutter原生剪贴板API完成复制
                await Clipboard.setData(ClipboardData(text: message.message));
                // 可选:给Web页面返回复制成功提示
                _webViewController.runJavascript('alert("文本已复制到剪贴板")');
              },
            );
          },
          onPageFinished: (url) {
            // 页面加载完成后,注入JS重写原页面的复制函数
            _webViewController.runJavascript('''
              function copyText() {
                var copyText = document.getElementById("myInput");
                copyText.select();
                copyText.setSelectionRange(0, 99999);
                // 将文本传递给Flutter端处理
                FlutterClipboard.postMessage(copyText.value);
              }
            ''');
          },
        ),
      ),
    );
  }
}

实现说明

  1. 注册JavaScript Channel:通过addJavaScriptChannel创建名为FlutterClipboard的通信通道,Web页面可通过该通道向Flutter传递要复制的文本。
  2. 重写Web页面复制逻辑:页面加载完成后注入JS代码,替换原有的copyText函数,保留原页面选中文本的视觉反馈,将复制操作转交给Flutter原生处理。
  3. Flutter原生复制:通过Clipboard.setData调用系统剪贴板API,不受WebView的JS权限限制,确保复制操作成功执行。

注意事项

  • 必须将javascriptMode设置为JavascriptMode.unrestricted,否则无法启用JavaScript Channel和注入JS代码。
  • 若为自定义Web页面,可直接在页面的复制逻辑中调用FlutterClipboard.postMessage(text),无需重写函数。
  • 无需额外权限依赖包,Flutter的Clipboard API无需申请系统权限。

内容的提问来源于stack exchange,提问作者Hunter ISMob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:40:07