Flutter WebView本地资源教程 文件加载与JS注入

在Flutter中加载本地资源到WebView时遇到问题:按照官方文档配置后,HTML文件仍无法正常加载,错误提示"无法访问本地文件"。尝试过使用flutter_inappwebviewwebview_flutter两个插件,但效果都不理想。具体疑问:

  1. 正确加载本地HTML资源的完整路径格式应该怎么写?是否需要特殊权限配置?
  2. 如何在加载完成后注入JS代码?测试发现onLoadStop事件中执行evaluateJavascript有时不生效
  3. 本地资源文件(如CSS/JS)如何与HTML关联?是否需要baseUrl特殊处理?
  4. 安卓和iOS在文件路径处理上是否有差异?遇到NETWORK_ERR该如何排查?

希望能提供可运行的完整示例,尤其是跨平台兼容的方案。


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

3 回复

作为屌丝程序员,下面简单介绍Flutter WebView加载本地资源和JS注入的方法:

  1. 加载本地HTML文件:使用loadUrl()方法加载本地HTML文件。首先将HTML文件放入assets目录,配置pubspec.yaml后,使用rootBundle.loadString()读取文件内容,再通过loadDataWithBaseUrl()加载。
final String content = await rootBundle.loadString('assets/index.html');
webViewController.loadUrl(Uri.dataFromString(
  content,
  mimeType: 'text/html',
  encoding: Encoding.getByName('utf-8')
).toString());
  1. JS注入:使用evaluateJavascript()方法执行JS代码。例如,假设要修改网页中的标题:
webViewController.evaluateJavascript("""
document.title = '新标题';
""");
  1. 注意事项:确保WebViewjavascriptMode设置为JavascriptMode.unrestricted,否则无法执行JS。

  2. 完整示例需引入webview_flutter插件,初始化WebViewController并配置相关参数。此方法适合开发混合应用,提升用户体验。

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


作为一个屌丝程序员,我来分享一下Flutter中WebView加载本地资源和JS注入的简单教程。

首先,确保依赖webview_flutter。接着,要加载本地HTML文件,可以使用如下代码:

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

class LocalWebView extends StatefulWidget {
  @override
  _LocalWebViewState createState() => _LocalWebViewState();
}

class _LocalWebViewState extends State<LocalWebView> {
  late WebViewController controller;

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

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

关于JS注入,可以用controller.evaluateJavascript()方法执行脚本。例如,在页面加载完成后执行JS代码:

controller.runJavascript("document.body.style.backgroundColor='blue';");

记得在pubspec.yaml中配置本地文件路径。这样就完成了简单的本地资源加载和JS注入操作!

Flutter WebView 本地资源加载与JS注入教程

本地资源加载

使用 flutter_inappwebview 插件可以轻松加载本地资源文件:

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

InAppWebView(
  initialData: InAppWebViewInitialData(
    data: """
      <!DOCTYPE html>
      <html>
        <body>
          <h1>本地HTML</h1>
          <script src="assets/js/local.js"></script>
        </body>
      </html>
    """,
    baseUrl: Uri.parse("file:///android_asset/flutter_assets/"),
    mimeType: "text/html",
    encoding: "utf-8",
  ),
)

JS注入方法

1. 初始化时注入

InAppWebView(
  initialOptions: InAppWebViewGroupOptions(
    crossPlatform: InAppWebViewOptions(
      javaScriptEnabled: true,
    ),
  ),
  onWebViewCreated: (controller) {
    controller.addJavaScriptHandler(
      handlerName: 'flutterHandler',
      callback: (args) {
        // 处理来自JS的调用
      },
    );
  },
  onLoadStop: (controller, url) async {
    await controller.evaluateJavascript(source: """
      // 你的JS代码
      console.log('JS注入成功');
      function callFlutter() {
        window.flutter_inappwebview.callHandler('flutterHandler', '参数');
      }
    """);
  },
)

2. 动态JS注入

Future<void> injectJS(InAppWebViewController controller) async {
  await controller.evaluateJavascript(source: """
    document.body.style.backgroundColor = 'red';
  """);
}

注意事项

  1. 确保在 pubspec.yaml 中正确配置了本地资源:
flutter:
  assets:
    - assets/js/local.js
  1. 对于 iOS,需要在 Info.plist 添加:
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>
  1. 在 Android 上,可能需要启用混合内容:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    webView.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}
回到顶部