如何从资产加载完整的网站?

How to load complete website from assets?

是否有可能从本地资产加载完整的网站(包括相关文件)?我用 flutter 插件 webview_flutter 试了一下,然后加载了 index.html.

  Future<String> loadLocal() async {
    return await rootBundle.loadString('assets/mywebsite/index.html');
  }

只有 html 代码正在呈现,关联的 javascript 不工作。

你可以关注https://github.com/flutter/flutter/issues/27086

与此同时,您可以在 Dart 中实现一个网络服务器,该服务器提供资产中的文件并将网络视图指向该集成网络服务器。

https://medium.com/@segaud.kevin/facebook-oauth-login-flow-with-flutter-9adb717c9f2e 是关于如何在 Dart 中做到这一点。

您也可以试试我的插件 flutter_inappwebview,这是一个 Flutter 插件,允许您添加内联 WebView 或打开应用内浏览器 window,并且有很多事件、方法、以及控制 WebView 的选项。

要从assets加载一个完整的网站,需要在pubspec.yaml文件中声明相应的文件:

...

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  assets:
    - assets/index.html
    - assets/page-1.html
    - assets/page-2.html
    - assets/js/
    - assets/css/
    - assets/images/

...

然后,您可以使用 InAppWebView 小部件的 initialFile 参数加载 index.html 文件:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

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

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialFile: "assets/index.html",
                    initialHeaders: {},
                    initialOptions: InAppWebViewWidgetOptions(
                      inAppWebViewOptions: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

                    },
                    onLoadStop: (InAppWebViewController controller, String url) {

                    },
                    onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
                      print(consoleMessage.message);
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

在你的 index.html 中,你会有这样的东西:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- this is a css file inside the assets folder -->
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <!-- this is a javascript file inside the assets folder -->
    <script src="js/main.js"></script>
</body>
</html>

我已经能够做到这一点,但它只在 Android 中有效。我通过以下方式使用了 InAppWebView 库:

 child: Container(
              child: InAppWebView(
                initialFile: "images/test.html",
                initialHeaders: {},
                onWebViewCreated: (InAppWebViewController controller) {
                  webView = controller;
                },
                onLoadStart: (InAppWebViewController controller, String url) {},
                onLoadStop: (InAppWebViewController controller, String url) {},
                onConsoleMessage: (InAppWebViewController controller,
                    ConsoleMessage consoleMessage) {
                  print(consoleMessage.message);
                },
              ),
            ),

html文件,包括相关文件已添加到项目资产中。