- 前端
- 跨平台
- 桌面应用
- 移动开发
【免费下载链接】flet
Build realtime web, mobile and desktop apps in Python only. No frontend experience required.
导读
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与其他类型(LogLevelSeverity、RequestMethod、WebViewConsoleMessageEvent、WebViewJavaScriptEvent、WebViewScrollEvent)一起被导出,因此在使用时通过import flet_webview as fwv之后,可以用fwv.JavaScriptMode.UNRESTRICTED或fwv.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.txt或pyproject.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;这里的controller是webview_flutter包提供的WebViewController,setJavaScriptMode()最终会作用于底层平台引擎:Android 上是WebSettings.setJavaScriptEnabled(),iOS/macOS 上是WKWebView的javaScriptEnabled配置。
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 不支持该控件。
注意事项
- 禁用 JS 可能导致页面行为异常:官方文档在
set_javascript_mode()的说明中明确提示"禁用页面的 JavaScript 执行可能导致意外的页面行为"。很多页面依赖脚本来渲染内容、处理表单、发起网络请求,将其禁用后页面可能白屏或功能失效。通常只应在"纯静态展示、增强安全性"等场景下使用。 - 在页面加载前后均可切换:从实现上看,
set_javascript_mode通过WebViewController.setJavaScriptMode在运行时生效,因此既可以在加载前设置,也可以在页面运行过程中切换(如上面的按钮示例)。 - 与
run_javascript()的关系:WebView还提供了run_javascript()方法(webview.py),用于在页面上下文中主动执行一段 JavaScript 代码。如果 JavaScriptMode 被设置为DISABLED,则页面自身的脚本不会运行;run_javascript()是宿主主动注入,两者语义不同,可搭配使用实现"宿主控制 + 页面静默"的混合交互模型。 - 配合控制台监听:当页面脚本运行时,可以通过
on_console_message事件(负载为WebViewConsoleMessageEvent,含message与severity_level)监听console.log/console.error等输出,结合JavaScriptMode与LogLevelSeverity构建调试或日志采集能力。
六、总结
JavaScriptMode是flet-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.
相关推荐
Flyway迁移脚本执行控制:shouldExecute配置详解
Flyway迁移脚本执行控制:shouldExecute配置详解 什么是shouldExecute配置 在数据库迁移工具Flyway中, shouldExecu
数据库开发工具Flet WebView 扩展实战指南:用 flet-webview 在 Python 应用中嵌入网页内容
Flet WebView 扩展实战指南:用 flet webview 在 Python 应用中嵌入网页内容 flet webview 是 Flet 官方推出的扩
前端跨平台桌面应用移动开发5分钟上手LSHash:从安装到索引百万级向量的实战指南
5分钟上手LSHash:从安装到索引百万级向量的实战指南 LSHash是一款基于随机投影的高效局部敏感哈希(Locality Sensitive Hashing
机器学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考