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

如何在flutter_inappwebview中打开about:blank新窗口并获取内容

解决Flutter WebView中打印按钮新开空白窗口的问题

问题说明

网页中的打印按钮(对应HTML代码:

<button onclick="printInvoice(127)" class="btn btn-success btn-lg">print</button>

)在浏览器中点击会新开标签页显示收据,但在Flutter应用中点击后,新窗口URL为about:blank且无响应,使用以下代码时还出现URL为null的问题:

onCreateWindow: (controller, createWindowRequest) async {
  await controller.loadUrl(urlRequest: createWindowRequest.request);
  
  String newWindowContent = await controller.evaluateJavascript(
    source: 'document.documentElement.outerHTML;',
  );
  print('New Window Content: $newWindowContent');
  
  return true;
},

解决方案

1. 用独立WebViewController监听内容加载

原网页的printInvoice函数大概率是先创建about:blank窗口,再通过JavaScript写入收据HTML内容。原代码直接复用当前controller加载空白请求,且立即执行evaluateJavascript,此时内容还未写入,导致获取失败。

修改为创建新的WebViewController处理新窗口,监听页面加载完成后再获取内容:

onCreateWindow: (controller, createWindowRequest) async {
  // 创建新的WebViewController处理新窗口
  final newWebViewController = WebViewController()
    ..setJavaScriptMode(JavaScriptMode.unrestricted);
  
  // 监听页面加载完成,确保内容已写入
  newWebViewController.onPageFinished.listen((url) async {
    if (url == 'about:blank') {
      // 等待JS完成内容写入(时长可根据网页实际情况调整)
      await Future.delayed(const Duration(milliseconds: 500));
      String newWindowContent = await newWebViewController.evaluateJavascript(
        source: 'document.documentElement.outerHTML;',
      );
      print('New Window Content: $newWindowContent');
      // 这里可添加展示或打印内容的逻辑
    }
  });

  await newWebViewController.loadUrl(urlRequest: createWindowRequest.request);
  
  // 可选:用弹窗展示新窗口内容
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('收据预览'),
      content: SizedBox(
        width: double.maxFinite,
        height: 600,
        child: WebViewWidget(controller: newWebViewController),
      ),
    ),
  );
  
  return true;
},

2. 直接拦截printInvoice函数(推荐)

如果能知晓printInvoice的具体逻辑,可注入JavaScript拦截该函数,直接获取收据内容,无需处理新窗口:

// 初始化WebViewController时注入拦截代码
WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted)
  ..addJavaScriptChannel(
    'PrintChannel',
    onMessageReceived: (JavaScriptMessage message) {
      // 接收收据HTML内容
      String invoiceHtml = message.message;
      print('Invoice HTML: $invoiceHtml');
      // 后续可用于展示或调用Flutter打印API
    },
  )
  ..loadRequest(Uri.parse('你的网页URL'))
  ..runJavascript('''
    // 重写原printInvoice函数
    window.printInvoice = function(id) {
      // 替换为原函数生成收据HTML的逻辑
      const invoiceHtml = 原函数生成HTML的代码;
      PrintChannel.postMessage(invoiceHtml);
      // 如需保留原打印行为,可添加window.print()
    };
  ''');

3. 检查WebView基础配置

确保开启JavaScript支持:

..setJavaScriptMode(JavaScriptMode.unrestricted)

若网页存在跨域内容,配置导航权限:

..setNavigationDelegate(
  NavigationDelegate(
    onNavigationRequest: (request) => NavigationDecision.navigate,
  ),
)

内容的提问来源于stack exchange,提问作者Sushang Nirola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:10:15