【问题标题】:Access --dart-define environment variables inside index.html在 index.html 中访问 --dart-define 环境变量
【发布时间】:2026-02-08 19:20:07
【问题描述】:

有什么方法可以访问 Flutter Web 的 index.html 文件中 --dart-define 命令定义的环境变量?

我目前可以在 iOS 和 Android 本机文件中访问它们,但在 html 文件中没有找到这样做的方法

【问题讨论】:

    标签: flutter dart flutter-web


    【解决方案1】:

    访问环境声明(这是最正确的名称,也用于String.fromEnvironment() 方法的文档中;另请参阅 dart-sdk issue #42136 - Clarify usage of -D/environment variables/environment declarations),也可以来自 javascript 代码。

    有两个细节需要牢记:

    • String.fromEnvironment() 只能用 const 调用(也是隐式的,在 const 上下文中),不能用“new”调用。
    • 在 Flutter/web 中,main() 方法不是在加载main.dart.js 脚本后立即执行,因此放置 js 脚本(在 main.dart.js 之后立即读取在 dart 中声明的变量。因此,当 dart 代码已执行时,有必要以某种方式向 js 代码发出信号。为了解决这个问题,我求助于自定义 DOM 事件。如果有更好的解决方案,我邀请您报告。

    示例:

    main.dart

    import 'package:flutter/material.dart';
    
    import 'dart:js' as js;
    import 'dart:html' as html;
    
    void main() {
      //To expone the dart variable to global js code
      js.context["my_dart_var"] = const String.fromEnvironment("my_dart_var");
      //Custom DOM event to signal to js the execution of the dart code
      html.document.dispatchEvent(html.CustomEvent("dart_loaded"));
    
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
       //...
    }
    

    index.html

      <script src="main.dart.js" type="application/javascript"></script>
    
      <script>
    
        //Here my_dart_var is undefined
        console.log(`my_dart_var: ${window.my_dart_var}`);
    
        document.addEventListener("dart_loaded", function (){
          //Here my_dart_var is defined
          console.log("dart_loaded event");
          console.log(`my_dart_var: ${window.my_dart_var}`);
        });
      </script>
    

    【讨论】:

    • 这不起作用:TypeError: Cannot read property 'app' of undefined
    • @rebar 我用新的 Flutter Sdk 2.2.0 再次测试了 sn-p(它在 index.html 中引入了一种新机制来加载 dart.main.js),它按预期工作. app 属性是什么? --dart-define 允许您仅定义原始类型(字符串、int、bool)的“环境声明”,所以我猜它不是您分配给环境声明的值的属性。
    • 这是 Firebase!您不能将此解决方案用于 firebase 应用程序!因为 Firebase 在 Dart 加载之前需要这些变量!因此:它可能适用于非 Firebase 项目,但截至目前,Firebase 项目因此缺乏安全性......
    • @rebar 我想我猜到了你想要做什么:1)如果你不采取这一步,Firebase 是安全的;在 index.html 中初始化它的令牌是公开的,因为即使其他人看到它们也不会有风险,因为它们只能在您在 firebase 控制台中设置的域(您的站点)中使用. 2)如果您仍想通过 dart-define 传递令牌,您可以使用 javascript 延迟加载 firebase 库
    • 另请注意,通过 dartdefine 传递的 env 声明是 const 在源代码中内联,因此在编译最终版本后,它们在 .js 文件中可见。因此不应该用于令牌保密(如上所述,在 index.html 中初始化 Fb 的令牌不应保密;您可以验证这一点通过谷歌搜索加深主题)。对于秘密令牌,网络托管服务通常提供一种特殊的机制(非常易于使用;我使用了 Netlify),也许 Firebase 也提供了类似的服务(可能是 Firebase Config,但我不记得了)。