Flutter WebView加载本地HTML文件并注入JS

在Flutter项目中,我尝试使用WebView加载本地HTML文件并注入JS脚本,但遇到了几个问题:

  1. 如何正确加载本地HTML文件?我将HTML文件放在assets文件夹中,但WebView无法识别路径,总是报404错误。

  2. JS注入的时机如何控制?我尝试在onPageFinished回调中调用evaluateJavascript,但有时JS不生效,可能是页面还未完全加载。是否有更可靠的注入方法?

  3. 如何确保WebView与Flutter之间的双向通信?我尝试用javascriptChannels接收JS消息,但偶尔收不到回调。

  4. 在iOS和Android上,WebView的行为不一致,比如本地文件加载和JS执行结果不同,该如何处理平台差异?

希望能得到具体的代码示例或解决方案!


更多关于Flutter WebView加载本地HTML文件并注入JS的实战教程也可以访问 https://www.itying.com/category-92-b0.html

3 回复

首先,将本地HTML文件添加到assets目录下并在pubspec.yaml中声明路径。使用WebView加载HTML文件时,通过loadUrl()方法结合javascriptMode设置为JavaScriptMode.unrestricted启用JS支持。

代码示例:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class LocalHtmlPage extends StatefulWidget {
  @override
  _LocalHtmlPageState createState() => _LocalHtmlPageState();
}

class _LocalHtmlPageState extends State<LocalHtmlPage> {
  late WebViewController _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: WebView(
        initialUrl: 'about:blank',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _controller = webViewController;
          _loadHtmlFromAssets();
        },
      ),
    );
  }

  void _loadHtmlFromAssets() async {
    String htmlContent = await rootBundle.loadString('assets/index.html');
    _controller.loadUrl(Uri.dataFromString(htmlContent, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString());
    _injectJs();
  }

  void _injectJs() {
    _controller.evaluateJavascript("""
      console.log('脚本已注入');
    """);
  }
}

确保HTML文件路径正确,并检查是否需要额外权限或依赖项。

更多关于Flutter WebView加载本地HTML文件并注入JS的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


作为屌丝程序员,我可以告诉你实现方法。首先创建一个Flutter项目,使用webview_flutter插件加载本地HTML。假设你的HTML文件放在assets目录下。

  1. pubspec.yaml添加:
dependencies:
  webview_flutter: ^4.2.0

并配置assets路径:

flutter:
  assets:
    - assets/
  1. 加载HTML代码如下:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewPage extends StatefulWidget {
  @override
  _WebViewPageState createState() => _WebViewPageState();
}

class _WebViewPageState extends State<WebViewPage> {
  late WebViewController controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: WebView(
        initialUrl: 'about:blank',
        onWebViewCreated: (WebViewController webViewController) {
          controller = webViewController;
          _loadHtmlFromAssets();
        },
      ),
    );
  }

  Future<void> _loadHtmlFromAssets() async {
    String htmlContent = await rootBundle.loadString('assets/index.html');
    controller.loadUrl(Uri.dataFromString(htmlContent, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString());
    _injectJs();
  }

  void _injectJs() {
    controller.evaluateJavascript("document.body.style.backgroundColor='red';");
  }
}

这样就能加载本地HTML并注入JS修改样式了。

在Flutter中加载本地HTML文件并注入JavaScript,可以使用webview_flutter插件。以下是一个完整的实现示例:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart' show rootBundle;

class LocalHtmlWithJs extends StatefulWidget {
  @override
  _LocalHtmlWithJsState createState() => _LocalHtmlWithJsState();
}

class _LocalHtmlWithJsState extends State<LocalHtmlWithJs> {
  late WebViewController _controller;
  String _htmlContent = "";

  @override
  void initState() {
    super.initState();
    _loadHtmlFromAssets();
  }

  Future<void> _loadHtmlFromAssets() async {
    String fileText = await rootBundle.loadString('assets/local_page.html');
    setState(() {
      _htmlContent = fileText;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('本地HTML+JS注入')),
      body: WebView(
        initialUrl: 'about:blank',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _controller = webViewController;
          _loadHtml();
        },
      ),
    );
  }

  void _loadHtml() {
    if (_htmlContent.isNotEmpty) {
      // 注入CSS/JS
      String injectedHtml = '''
        $_htmlContent
        <script>
          // 这里可以添加你的JavaScript代码
          alert('JS注入成功!');
          document.body.style.backgroundColor = "#f0f0f0";
        </script>
      ''';
      
      _controller.loadUrl(Uri.dataFromString(
        injectedHtml,
        mimeType: 'text/html',
        encoding: Encoding.getByName('utf-8'),
      ).toString());
    }
  }
}

关键点说明:

  1. 将HTML文件放在assets文件夹,并在pubspec.yaml中声明
  2. 使用rootBundle.loadString读取本地HTML文件
  3. 通过data: URI方案加载HTML内容
  4. 直接在HTML字符串中嵌入JavaScript代码

注意事项:

  • 确保添加网络权限(Android)和ATS配置(iOS)
  • 对于复杂的JS交互,建议使用javascriptChannels
  • 如果JS不执行,检查是否启用javascriptMode.unrestricted

需要更复杂的JS交互时,可以使用evaluateJavascript方法:

_controller.evaluateJavascript('yourJavaScriptCode()');
回到顶部