Flutter:Web 视图安全源

Posted

技术标签:

【中文标题】Flutter:Web 视图安全源【英文标题】:Flutter: Web View Secure Origin 【发布时间】:2019-06-25 11:52:30 【问题描述】:

加载 Youtube 视频时,Flutter Webview (webview_flutter: ^0.1.2) 出现错误,(虽然我最初认为它与内容安全问题有关),这似乎是 HTTPS 上的安全来源问题。在浏览器上,这通常可以通过转移到 HTTPS 域来缓解,在移动设备上寻找解决这个问题的方法

             Container(
                child: WebView(
                         initialUrl: Uri.dataFromString(
                          '<html>'
                            '<meta http-equiv="Content-Security-Policy" content="default-src * gap:; script-src * \'unsafe-inline\' \'unsafe-eval\'; connect-src *; img-src * data: blob: android-webview-video-poster:; style-src * \'unsafe-inline\';">'
//                            '<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">'
                            '<body><iframe src="https://www.youtube.com/embed/vlkNcHDFnGA"></iframe></body>'
                          '</html>', mimeType: 'text/html').toString(),
                      javascriptMode: JavascriptMode.unrestricted,                )),

我在控制台中看到以下内容:https://www.youtube.com/embed/vlkNcHDFnGA%22%3E%3C/iframe%3E%3C/body%3E%3C/html%3E (1)

在不安全的来源上不推荐使用 deviceorientation 事件,并且 将来将删除支持。你应该考虑换 将您的应用程序转移到安全来源,例如 HTTPS。看 https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins 了解更多详情。

【问题讨论】:

问题中引用的错误消息不是 CSP 错误消息,与 CSP 没有任何关系。相反,它似乎表明浏览器引擎将您的内容本身(而不是您的内容可能嵌入的任何特定外部资源,这就是 CSP 所涉及的)视为来自不安全的来源 - 例如,http 来源而不是https 来源。 没错,我在浏览器上遇到了同样的问题,我们通过将域移至 https 来解决它,我们如何在移动设备上做到这一点 据我了解,WebView 上下文是在 webview 中加载的页面,如果该页面是安全的,那么上下文也将是安全的。您似乎在那里有内联 HTML,因此可能不安全。也许嵌入 iframe 的 webview 不是最好的主意,也许直接查看 iframe 源会更好。不过不太确定。 我用的是同款,不知道怎么解决这个问题? 【参考方案1】:

你可以试试我的插件flutter_inappwebview,这是一个Flutter插件,允许你添加内联WebViews或打开一个应用内浏览器窗口,并且有很多事件、方法和选项来控制WebViews。

要在 WebView 中加载&lt;iframe&gt;,您可以使用InAppWebView 小部件的initialData 参数直接加载HTML 源代码,或者使用initialFile参数。

使用 initialData 参数和您的 youtube 链接的完整示例:

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;
  String iframeUrl = "https://www.youtube.com/embed/vlkNcHDFnGA";

  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialData: InAppWebViewInitialData(
                        data: """
<!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">
        <title>Flutter InAppWebView</title>
    </head>
    <body>
        <iframe src="$iframeUrl"   frameborder="0" allowfullscreen></iframe>
    </body>
</html>"""
                    ),
                    initialHeaders: ,
                    initialOptions: InAppWebViewWidgetOptions(
                      inAppWebViewOptions: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) 
                      webView = controller;
                    ,
                    onLoadStart: (InAppWebViewController controller, String url) 

                    ,
                    onLoadStop: (InAppWebViewController controller, String url) 

                    ,
                  ),
                ),
              ),
            ]))
    );
  

【讨论】:

在 android 上运行良好,但在 ios 上加载时卡住了

以上是关于Flutter:Web 视图安全源的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Flutter Web 视图中使用本地存储

Flutter WEB的Firebase Analytics调试视图?

Flutter Web App 在手机桌面视图中的奇怪行为

升级到 Flutter 2.0 会破坏 Flutter Firebase Web 项目

如何防止platformViewRegistry出错[flutter-web]

浅析Flutter的架构设计