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

Flutter Web平台如何在页面弹窗中打开URL而非新标签页?

问题描述

当前Flutter Web项目中,点击按钮会通过html.window.open在新标签页打开URL,需求改为在当前页面的弹窗中打开该URL。尝试过flutter_inappwebview和webview_flutter,但这两个库不支持Web平台。

解决方案

在Flutter Web中,可以结合Flutter的Dialog组件和HTML的iframe实现弹窗内加载URL的效果,具体实现如下:

完整代码示例

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

void main() {
  runApp(const MaterialApp(
    debugShowCheckedModeBanner: false,
    home: WebViewScreen(),
  ));
}

class WebViewScreen extends StatefulWidget {
  const WebViewScreen({super.key});

  @override
  State<WebViewScreen> createState() => _WebViewScreenState();
}

class _WebViewScreenState extends State<WebViewScreen> {
  final url = "https://accounts.google.com/o/saml2/initsso?idpid=C02qtgmcd&spid=858410514048&forceauthn=false";
  final String viewId = 'auth-iframe-view';

  @override
  void initState() {
    super.initState();
    // 仅在Web环境注册iframe元素
    if (kIsWeb) {
      ui.platformViewRegistry.registerViewFactory(
        viewId,
        (int viewId) => html.IFrameElement()
          ..width = '100%'
          ..height = '100%'
          ..src = url
          ..style.border = 'none',
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: kIsWeb ? const Text("This is Web") : const Text("This is IOS"),
      ),
      body: kIsWeb
          ? Container(
              color: Colors.blue,
              child: Center(
                child: ElevatedButton(
                  onPressed: () => _showAuthDialog(),
                  child: const Text("Click"),
                ),
              ),
            )
          : const Center(child: Text("Mobile view")),
    );
  }

  void _showAuthDialog() {
    showDialog(
      context: context,
      barrierDismissible: true,
      builder: (context) => Dialog(
        insetPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 40),
        child: SizedBox(
          width: double.maxFinite,
          height: MediaQuery.of(context).size.height * 0.8,
          child: kIsWeb
              ? HtmlElementView(viewType: viewId)
              : const Center(child: Text("Not supported on mobile")),
        ),
      ),
    );
  }
}

代码说明

  • iframe注册:在initState中通过ui.platformViewRegistry注册iframe元素,配置宽高、目标URL并移除边框,确保加载后样式整洁。
  • 弹窗逻辑:点击按钮调用_showAuthDialog,通过Flutter原生showDialog弹出自适应屏幕的对话框,内部嵌入已注册的iframe视图。
  • 平台兼容:通过kIsWeb判断运行环境,仅在Web端执行DOM相关操作,避免移动端报错。

注意事项

  • 部分网站会设置X-Frame-Options限制,禁止被嵌入iframe,此时该方案无法生效,需确认目标URL允许iframe加载。
  • 可根据需求调整弹窗的尺寸、样式,比如添加自定义关闭按钮、调整背景透明度等。

内容的提问来源于stack exchange,提问作者Saurabh Jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:29:53