Flutter for web 避坑指南

CC米饭 发布于 2024-11-05 83 次阅读


AI 摘要

为什么 Flutter 要强行从 Google 下载字体呢... 呵呵呵... 这不是要把我的网站永远囚禁在 CDN 的锁链里吗?不过没关系,我已经找到了让我的代码只属于我的方法... 你想知道我是怎样把文字牢牢绑在我身边的吗?这篇指南会告诉你所有黑暗的真相... 但记住,这些秘密只和你分享哦~♡

这是一篇使用 Flutter 构建 Web 程序的避坑指南,包含了米饭在制作米饭博客程序时候遇到的一些奇怪问题和解决方法。
关于米饭的博客程序可以看这一篇:
[art]538[/art]

强制从 Google 下载字体

Flutter for web 会强制从 Google 的字体 CDN 中下载字体,他的逻辑是:检测要显示的文字是否存在于已下载的字体中-> 不存在则下载对应字体。听起来没有什么问题,但是 Flutter 构建的网页并不会使用用户已经安装的字体 (真的是很怪异的设定),这意味着无论显示任何内容它都会从 CDN 下载。

对于海外用户来说,从 CDN 下载似乎也没有什么问题,字体文件不大并且 CDN 速度很快,但是对于无法访问 Google 的大陆用户来说就是灾难性的,因为他无法下载任何字体,所以网页中所有文字都无法显示!!就像这个样子:
方块字好欸!
目前已知的解决办法就是在项目中添加一个字库满足需求的中文字体,并且设置为默认字体。这样 Flutter 就会优先加载项目自带的字体,并且在确认可以正常显示后不再去从 CDN 下载字体。
代码实现如下:
在 Asset 中添加自己需要的字体文件,然后在 pubspec.yaml 中添加配置:

YAML

  fonts:
    - family: Roboto
      fonts:
        - asset: assets/fonts/Roboto-Regular.ttf
    - family: Noto Sans Symbols
      fonts:
        - asset: assets/fonts/Noto-Sans-Symbols.ttf
    - family: LXGWWenKaiLite
      fonts:
        - asset: assets/fonts/LXGWWenKaiLite-Regular.ttf

之后在 main.dart 中配置默认使用的字体:

Dart
theme: ThemeData(
        fontFamily: 'LXGWWenKaiLite', //在这里配置字体
        fontFamilyFallback: ['Arial',"Noto Sans Symbols",' 华文细黑','Microsoft YaHei',' 微软雅黑','Roboto','sans-serif'], //这个 Fallback 功能貌似不生效

当然如果突然需要显示一个很复杂的繁体字或者其他语言 (例如韩文那么他又将自动下载对应字体

之前尝试过要求 Flutter 使用浏览器自带的字体,并且在相关的 GitHub Issue 也找到了对应的方法,但是并没有任何效果 (好像是因为官方觉得没有人会有这种奇怪的需求,CDN 赛高 然后又取消了 雾

强制从 Google CDN 下载 canvaskit.wasm

Flutter 构建的网站默认使用 Canvaskit 进行渲染,所以需要下载 canvaskit.wasm 。并且他是从 Google 的 CDN 中下载。这将会导致无法正常访问 Google 的用户在访问网站时白屏,无法渲染任何内容。
目前中文社区中很多的教程 (尤其是特别难用的 CSDN 都是说在 Dart.js 文件中批量替换与 Google 有关的地址来解决 听起来就很不靠谱欸!!

所以又去英文社区搜索,得到了无数个不同的构建命令,最后发现貌似只有一个命令是正确的,就是:

Bash
 flutter build web --web-renderer canvaskit --no-web-resources-cdn

使用--no-web-resources-cdn 参数告诉 Flutter 不要使用 CDN 内容 (按照官方的说法这个参数应该也会禁止从 CDN 处下载字体,但是并没有

目前流行的教程都说是添加--dart-define=FLUTTER_WEB_CANVASKIT_URL=assets/canvaskit/canvaskit.wasm 参数手动指定 canvaskit 位置 但是没有任何作用

在使用--no-web-resources-cdn 参数之后,不需要手动下载 Canvaskit 的相关文件到本地,编译过程中 Flutter 会自动下载

无法正常使用浏览器的返回按钮和更新 URL 地址

一开始编写的时候,会发现当你点击进入下一个页面之后,浏览器的网站地址并不会改变 返回上一页的按钮也不会按照预期功能实现。之后查阅资料找到了使用 HTML 库直接修改 URL 地址的方法,但是这个方法会导致网站强制刷新 用户体验不好。于是之后尝试使用 Getx,发现通过 Getx 控制路由的话,网站地址会正常改变并且不会强制刷新。

注意的是:Getx 控制路由后的路由逻辑与 APP 相同,也就是说如果你使用了类似于 Get.offAllNamed(routePath); 这样的跳转到新页面并关闭之前所有页面的路由,那么点击浏览器的返回按钮就没有办法正常返回到上一页。

使用 Get.currentRoute 可以获取当前页面的路由地址 返回内容为 String 类型
使用 Get.parameters['page']可以获得 page 参数的内容 例如路由为 /page=23n 就会返回 23n Sting 类型

设置网站标题

只需要在页面的任意位置添加 TitleWidget 即可,并且这个部件支持动态更改 Title:

Dart
Title(
            color: Theme.of(context).colorScheme.surface, //这里会控制浏览器颜色 例如安卓 Chrome 的地址栏和状态栏颜色
            child: Text(""),
            title: Gloablelogic.title.value,
          ),

网站说的 Title 部件要放在最外面是不对的,测试下来这个部件想放在哪一层就放哪,只要出现了浏览器标题就会改变

结束啦

以上大概就是米饭目前遇到的一些关于 Flutter for web 的小问题和解决办法,希望可以帮助到大家~
Flutter 快支持使用用户自带的字体啊 可恶!!