Flet WebView 的 JavaScriptMode 详解:控制页面脚本执行与移动端实践
2026/9/23 6:36:49 网站建设 项目流程
  • 前端
  • 跨平台
  • 桌面应用
  • 移动开发

【免费下载链接】flet

Build realtime web, mobile and desktop apps in Python only. No frontend experience required.

项目地址:https://gitcode.com/gh_mirrors/fl/flet
点击查看免费下载

导读

JavaScriptMode是 Flet 生态中 flet-webview 扩展为WebView控件提供的 JavaScript 执行模式枚举,用于定义加载页面中脚本的运行状态。本指南以 JavaScriptMode 官方文档 为核心,结合其所在的flet-webview扩展源码与示例,系统讲解它的两个成员值、默认行为、底层 Flutter 调用链、受限平台,以及在实际应用中如何用它配合run_javascript()on_console_message等 API 构建可控的混合应用页面。读完本文,你将能够在 Flet 的 iOS、Android 与 macOS 应用里精确控制 WebView 的脚本执行开关,并理解禁用 JavaScript 后页面可能出现的行为变化。

一、JavaScriptMode 是什么

JavaScriptMode定义在flet-webview扩展的 types.py 中,是一个基于 Python 标准库Enum的枚举类型,其完整定义为:

class JavaScriptMode(Enum): """Defines the state of JavaScript support in the `WebView`.""" UNRESTRICTED = "unrestricted" """JavaScript execution is unrestricted.""" DISABLED = "disabled" """JavaScript execution is disabled."""

从源码注释可以看到:

  • UNRESTRICTED:JavaScript 执行不受限制,即页面中的脚本可以正常运行;
  • DISABLED:JavaScript 执行被禁用,页面中的脚本不会运行。

它只存在于flet-webview扩展中,属于该扩展的公开 API。在扩展包的 __init__.py 中,JavaScriptMode与其他类型(LogLevelSeverityRequestMethodWebViewConsoleMessageEventWebViewJavaScriptEventWebViewScrollEvent)一起被导出,因此在使用时通过import flet_webview as fwv之后,可以用fwv.JavaScriptMode.UNRESTRICTEDfwv.JavaScriptMode.DISABLED来引用。

需要强调的是,JavaScriptMode的底层字符串值"unrestricted""disabled"是 Python 层与 Flutter 层之间的协议值,它们在 Dart 端通过parseEnum解析为webview_flutter包中的JavaScriptMode枚举,这一点将在下文"源码级实现链路"中展开。

二、JavaScriptMode 的两种模式与默认行为

JavaScriptMode只有两个成员,语义非常清晰:

成员含义
UNRESTRICTED"unrestricted"JavaScript 执行不受限制(默认)
DISABLED"disabled"JavaScript 执行被禁用

关键默认行为,在 webview.py 的set_javascript_mode()方法文档中写得很明确:

默认为flet_webview.JavaScriptMode.UNRESTRICTED,并且在页面第一次加载之前就会应用。

也就是说,只要你不显式调用set_javascript_mode()WebView就会以"JavaScript 完全可用"的状态加载页面。这一点对大多数依赖脚本渲染的现代网页(如使用 React/Vue 构建的 SPA、需要登录鉴权的站点)都是必要的。

三、在 WebView 中设置与切换 JavaScriptMode

3.1 安装扩展

flet-webview是独立的 Flet 扩展包,需要先安装才能使用(官方文档见 WebView 控件说明):

# 使用 uv uv add flet-webview # 或使用 pip pip install flet-webview

使用pip安装后,还需要手动把flet-webview添加进requirements.txtpyproject.toml,以保证项目依赖完整可复现。

3.2 基础用法:创建 WebView

flet-webview的官方示例位于 extensions/web_view/web_view/main.py,展示了最基础的用法:

import flet as ft import flet_webview as fwv def main(page: ft.Page): page.add( ft.SafeArea( expand=True, content=fwv.WebView( url="https://flet.dev", on_page_started=lambda _: print("Page started"), on_page_ended=lambda _: print("Page ended"), on_web_resource_error=lambda e: print("WebView error:", e.data), expand=True, ), ) ) if __name__ == "__main__": ft.run(main)

在这个基础上,WebView控件还提供了导航(go_back/go_forward/reload)、缩放(enable_zoom/disable_zoom)、缓存清理(clear_cache/clear_local_storage)、页面信息获取(get_current_url/get_title/get_user_agent)等一组异步方法,完整清单见 webview.py。

3.3 用 set_javascript_mode 切换执行模式

JavaScriptMode的使用入口是WebView.set_javascript_mode(),这是一个异步方法,定义如下(webview.py):

async def set_javascript_mode(self, mode: JavaScriptMode): """ Sets the JavaScript mode of the WebView. ... Args: mode: The JavaScript mode to set. """ self._check_mobile_or_mac_platform() await self._invoke_method( method_name="set_javascript_mode", arguments={"mode": mode}, )

一个完整的实践示例——先以默认模式加载页面,再通过按钮切换 JavaScript 的开关:

import flet as ft import flet_webview as fwv async def main(page: ft.Page): wv = fwv.WebView(url="https://example.com", expand=True) async def toggle_js(e: ft.ControlEvent): if e.control.text == "禁用 JavaScript": await wv.set_javascript_mode(fwv.JavaScriptMode.DISABLED) e.control.text = "启用 JavaScript" else: await wv.set_javascript_mode(fwv.JavaScriptMode.UNRESTRICTED) e.control.text = "禁用 JavaScript" page.update() page.add( ft.Column( [ ft.FilledButton(text="禁用 JavaScript", on_click=toggle_js), wv, ], expand=True, ) ) ft.run(main)

四、源码级实现链路:从 Python 枚举到 Flutter 引擎

JavaScriptMode虽小,其背后是一条完整的"Python → Flutter 通道 → 平台 WebView"调用链,理解它有助于排查问题。

4.1 Python 层:类型定义与参数传递

Python 侧的类型定义与参数序列化位于 types.py。当调用set_javascript_mode()时,_invoke_method会把mode枚举值字符串"unrestricted""disabled")作为参数传给 Flutter 端。

4.2 Flutter 层:协议解析与引擎调用

在 Flutter 端,扩展包的 utils/webview.dart 负责把协议字符串解析回 Dart 枚举:

JavaScriptMode? parseJavaScriptMode(String? value, [JavaScriptMode? defaultValue]) { return parseEnum(JavaScriptMode.values, value, defaultValue); }

随后在 webview_mobile_and_mac.dart 的_invokeMethod分发中处理:

case "set_javascript_mode": var mode = parseJavaScriptMode(args["mode"]); if (mode != null) { await controller.setJavaScriptMode(mode); } break;

这里的controllerwebview_flutter包提供的WebViewControllersetJavaScriptMode()最终会作用于底层平台引擎:Android 上是WebSettings.setJavaScriptEnabled(),iOS/macOS 上是WKWebViewjavaScriptEnabled配置。

4.3 平台差异:Android 默认关闭 JS 的坑

值得特别注意的是,在 webview_mobile_and_mac.dart 的初始化逻辑中,有一段专门的注释与处理:

Android 的WebSettings.javaScriptEnabled默认是false,与WKWebView和 Web 平台不同,页面会静默地不运行任何脚本。因此扩展在首次加载之前先启用 JS(JavaScriptMode.unrestricted),之后可以通过set_javascript_mode再关闭它。

// Android's WebSettings.javaScriptEnabled defaults to false, unlike // WKWebView and the web platform, so a page would silently run no script // there. Enable it before the first load; `set_javascript_mode` can turn // it back off afterwards. controller.setJavaScriptMode(JavaScriptMode.unrestricted).then((_) => _load(...));

这正是"默认行为为 UNRESTRICTED"的实现保证——如果不做这一步,Android 上的页面会静默丢失全部脚本行为,而 iOS/macOS 的 WKWebView 与 Web 平台本身就默认开启 JS。

五、JavaScriptMode 的适用平台与注意事项

JavaScriptMode并非在所有平台上都可用。从 webview.py 中的平台校验逻辑可以看出,set_javascript_mode()WebView的大多数方法一样,仅支持 iOS、Android、macOS 三个平台:

def _check_mobile_or_mac_platform(self): if self.page is None: raise RuntimeError("WebView must be added to page first.") if self.page.web or self.page.platform not in [ ft.PagePlatform.ANDROID, ft.PagePlatform.IOS, ft.PagePlatform.MACOS, ]: raise ft.FletUnsupportedPlatformException( "This method is supported on Android, iOS and macOS platforms only." )

也就是说:

  • 支持:iOS、Android、macOS;
  • 不支持:Web(浏览器端)、Windows、Linux。

在不受支持的平台上调用该方法会抛出FletUnsupportedPlatformException。与之对应,WebView 控件官方文档 中给出的平台支持矩阵为:macOS、iOS、Android、Web 支持WebView本身,而 Windows、Linux 不支持该控件。

注意事项

  1. 禁用 JS 可能导致页面行为异常:官方文档在set_javascript_mode()的说明中明确提示"禁用页面的 JavaScript 执行可能导致意外的页面行为"。很多页面依赖脚本来渲染内容、处理表单、发起网络请求,将其禁用后页面可能白屏或功能失效。通常只应在"纯静态展示、增强安全性"等场景下使用。
  2. 在页面加载前后均可切换:从实现上看,set_javascript_mode通过WebViewController.setJavaScriptMode在运行时生效,因此既可以在加载前设置,也可以在页面运行过程中切换(如上面的按钮示例)。
  3. run_javascript()的关系WebView还提供了run_javascript()方法(webview.py),用于在页面上下文中主动执行一段 JavaScript 代码。如果 JavaScriptMode 被设置为DISABLED,则页面自身的脚本不会运行;run_javascript()是宿主主动注入,两者语义不同,可搭配使用实现"宿主控制 + 页面静默"的混合交互模型。
  4. 配合控制台监听:当页面脚本运行时,可以通过on_console_message事件(负载为WebViewConsoleMessageEvent,含messageseverity_level)监听console.log/console.error等输出,结合JavaScriptModeLogLevelSeverity构建调试或日志采集能力。

六、总结

JavaScriptModeflet-webview中控制 WebView 页面脚本执行状态的极简枚举,只有UNRESTRICTED(默认、不受限制)与DISABLED(禁用)两个取值。在实际的 Flet 应用中,你可以:

  • 默认保持UNRESTRICTED,让现代网页正常渲染与交互;
  • 在需要"纯内容展示"或提高页面可控性时,通过异步方法set_javascript_mode(JavaScriptMode.DISABLED)关闭脚本;
  • 在运行时动态切换两种模式,配合run_javascript()on_console_message构建宿主与页面深度协作的混合应用。

需要注意的是,该能力仅适用于 iOS、Android、macOS 三个平台,且 Android 平台默认关闭 JS 的特性已被扩展内部自动兜底处理,你无需额外配置即可获得与其他平台一致的默认体验。若要进一步探索,可阅读 WebView 控件文档、扩展包的类型定义 types.py 与官方示例 web_view/main.py。

  • 前端
  • 跨平台
  • 桌面应用
  • 移动开发

【免费下载链接】flet

Build realtime web, mobile and desktop apps in Python only. No frontend experience required.

项目地址:https://gitcode.com/gh_mirrors/fl/flet
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询