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

Flutter中使用iframe遇阻:WebView与html包均无效求解决方案

在Flutter中嵌入iframe遇到的问题

我想在Flutter中使用如下iframe:

<iframe
src="https://www.example"
width="100%"
style="height: 100%; min-height: 700px"
frameborder="0"
></iframe>

我尝试过使用WebView(已弃用)和html包实现,但都无法正常显示iframe。改用html包后结果依旧无效,以下是我的代码:

import 'dart:html' as html;
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

class ChatbotWidget extends StatefulWidget {
  @override
  _ChatbotWidgetState createState() => _ChatbotWidgetState();
}

class _ChatbotWidgetState extends State<ChatbotWidget> {
  @override
  void initState() {
    super.initState();

    // Register the chatbot iframe
    final iframe = html.IFrameElement()
      ..src = 'https://www.chatbase.co/chatbot-iframe/e722IpwL3HEm27U2KOodE'
      ..style.border = 'none'
      ..style.width = '100%'
      ..style.height = '100%'
      ..style.minHeight = '700px';

    // Add script to head for chatbot
    final scriptConfig = html.ScriptElement()
      ..type = 'text/javascript'
      ..innerHtml = '''
        window.embeddedChatbotConfig = {
          chatbotId: "e722IpwL3HEm27U2KOodE",
          domain: "www.chatbase.co"
        };
      ''';

    final script = html.ScriptElement()
      ..src = 'https://www.chatbase.co/embed.min.js'
      ..defer = true;

    html.document.head!.append(scriptConfig);
    html.document.head!.append(script);

    // Register the iframe element
    ui.platformViewRegistry.registerViewFactory(
      'iframeElement',
      (int viewId) => iframe,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: double.infinity,
      child: HtmlElementView(viewType: 'iframeElement'),
    );
  }
}

我是Flutter新手,代码可能不够规范,希望得到有效的解决方法。


解决方法

你的代码存在几个关键问题,调整后即可正常显示iframe:

1. 避免重复注册视图工厂

ui.platformViewRegistry.registerViewFactory 应该只执行一次,多次执行会导致冲突。可以用静态变量标记是否已完成注册,避免重复操作。

2. 给容器设置明确的尺寸约束

Container 设置 width 和 height 为 double.infinity 可能导致布局约束不足,建议给容器设置具体的最小高度,或者用 Expanded 包裹让它填充父组件空间。

3. 优化脚本与iframe的加载逻辑

不需要同时添加脚本和iframe,Chatbase的嵌入脚本会自动生成iframe,你可以二选一:要么直接使用独立iframe,要么用官方脚本实现。

修正方案一:直接使用独立iframe

import 'dart:html' as html;
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

class ChatbotWidget extends StatelessWidget {
  static bool _isRegistered = false;

  ChatbotWidget() {
    if (!_isRegistered) {
      final iframe = html.IFrameElement()
        ..src = 'https://www.chatbase.co/chatbot-iframe/e722IpwL3HEm27U2KOodE'
        ..style.border = 'none'
        ..style.width = '100%'
        ..style.height = '700px';

      ui.platformViewRegistry.registerViewFactory(
        'chatbot-iframe',
        (int viewId) => iframe,
      );
      _isRegistered = true;
    }
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 700,
      width: double.infinity,
      child: HtmlElementView(viewType: 'chatbot-iframe'),
    );
  }
}

修正方案二:使用Chatbase官方嵌入脚本(更推荐)

如果iframe方式无法正常加载,直接用官方提供的嵌入脚本实现:

import 'dart:html' as html;
import 'package:flutter/material.dart';

class ChatbotWidget extends StatefulWidget {
  @override
  _ChatbotWidgetState createState() => _ChatbotWidgetState();
}

class _ChatbotWidgetState extends State<ChatbotWidget> {
  @override
  void initState() {
    super.initState();
    if (html.document.getElementById('chatbase-script') == null) {
      // 添加配置脚本
      final configScript = html.ScriptElement()
        ..id = 'chatbase-config'
        ..type = 'text/javascript'
        ..innerHtml = '''
          window.embeddedChatbotConfig = {
            chatbotId: "e722IpwL3HEm27U2KOodE",
            domain: "www.chatbase.co"
          };
        ''';
      html.document.head!.append(configScript);

      // 添加嵌入脚本
      final embedScript = html.ScriptElement()
        ..id = 'chatbase-script'
        ..src = 'https://www.chatbase.co/embed.min.js'
        ..defer = true;
      html.document.head!.append(embedScript);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: 700,
      alignment: Alignment.center,
      child: const Text('聊天机器人加载中...'),
    );
  }
}

关键注意事项

  • 以上方案仅适用于Flutter Web,因为依赖dart:html和ui.platformViewRegistry,移动端无法使用这些API。如果要在移动端实现,需使用webview_flutter包替代已弃用的WebView。
  • 确保Flutter项目已配置Web支持,运行flutter run -d chrome测试效果。
  • 检查目标iframe地址是否允许跨域嵌入,若对方网站禁止iframe嵌入,需对方配置相关权限。

内容的提问来源于stack exchange,提问作者Andre wijaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:14:52