Flutter WebViewPlus报错:Unsupported operation: ServerSocket.bind
解决Flutter Web使用webview_flutter_plus加载本地HTML时的"Unsupported operation: ServerSocket.bind"错误
问题原因
webview_flutter_plus加载本地HTML的核心机制是启动本地Socket服务器托管静态资源,但Flutter Web运行在浏览器沙箱环境中,浏览器禁止Dart/JavaScript创建本地ServerSocket,因此触发该错误。该包的本地文件加载功能仅支持iOS/Android平台,天然不兼容Web平台。
解决方案
方案1:改用webview_flutter直接加载本地HTML(Web平台兼容)
如果不需要webview_flutter_plus的高度自适应等扩展功能,直接用官方的webview_flutter即可在Web平台正常加载本地HTML:
- 将
files/content.html移动到Flutter项目的web目录下(Flutter Web的资源根目录为web) - 修改main.dart代码,替换为webview_flutter组件并配置正确路径:
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() { runApp(const WebViewExample()); } class WebViewExample extends StatelessWidget { const WebViewExample({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MaterialApp( home: WebViewExampleMainPage(), ); } } class WebViewExampleMainPage extends StatefulWidget { const WebViewExampleMainPage({Key? key}) : super(key: key); @override _WebViewExampleMainPageState createState() => _WebViewExampleMainPageState(); } class _WebViewExampleMainPageState extends State<WebViewExampleMainPage> { WebViewController? _controller; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('WebView Local HTML Example'), ), body: WebView( initialUrl: Uri.base.resolve('content.html').toString(), onWebViewCreated: (controller) { _controller = controller; }, javascriptMode: JavascriptMode.unrestricted, ), ); } }
方案2:保留webview_flutter_plus但仅在移动端运行
如果必须依赖webview_flutter_plus的高度自适应等功能,可通过平台判断限制仅在iOS/Android平台启用该组件,Web平台做兼容提示:
import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:webview_flutter_plus/webview_flutter_plus.dart'; // 其余代码保持不变,仅修改build方法 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('webview_flutter_plus Example')), body: kIsWeb ? const Center(child: Text('Web平台不支持该功能,请使用移动端打开')) : ListView( children: [ Text("Height of WebviewPlus: $_height", style: const TextStyle(fontWeight: FontWeight.bold)), SizedBox( height: _height, child: WebViewPlus( serverPort: 5353, initialUrl: 'files/content.html', onWebViewCreated: (controller) => _controller = controller, onPageFinished: (url) { _controller?.getHeight().then((height) => setState(() => _height = height)); }, javascriptMode: JavascriptMode.unrestricted, ), ) ], ), ); }
方案3:Web平台手动实现高度自适应(替代webview_flutter_plus)
如果需要在Web平台同时实现本地HTML加载和高度自适应,可通过JS与Flutter通信获取页面高度:
- 修改web目录下的content.html,添加JS代码发送高度到Flutter:
<html> <head> <title> Test </title> <script> window.addEventListener('load', () => { // 发送页面实际高度给Flutter window.flutterPageHeight.callHandler('updateHeight', document.body.scrollHeight); }); </script> </head> <body> <h1> Test </h1> </body> </html>
- 在main.dart中配置webview_flutter接收高度并更新UI:
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; // 其余代码保持不变,仅修改WebView配置 class _WebViewExampleMainPageState extends State<WebViewExampleMainPage> { WebViewController? _controller; double _height = 1; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('WebView Height Adaptive')), body: ListView( children: [ Text("Height of WebView: $_height", style: const TextStyle(fontWeight: FontWeight.bold)), SizedBox( height: _height, child: WebView( initialUrl: Uri.base.resolve('content.html').toString(), onWebViewCreated: (controller) { _controller = controller; // 注册JS回调通道 controller.addJavaScriptChannel( 'flutterPageHeight', onMessageReceived: (message) { setState(() { _height = double.parse(message.message); }); }, ); }, javascriptMode: JavascriptMode.unrestricted, ), ) ], ), ); } }
内容的提问来源于stack exchange,提问作者timo1998
相关产品推荐
相关产品推荐

