有没有办法在 Flutter WebView 中导入外部脚本
Posted
技术标签:
【中文标题】有没有办法在 Flutter WebView 中导入外部脚本【英文标题】:Is there a way to import external scripts in Flutter WebView 【发布时间】:2020-07-08 06:19:03 【问题描述】:我正在尝试将外部脚本加载到 Flutter WebView 中,但它似乎不起作用。特别是关于 tinyMCE。所以目的是在一个AlertDialog中打开一个富文本编辑器,里面有WebView。这可能吗?
以下是我的html:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.2.1/tinymce.min.js"></script>
</head>
<body>
<textarea id="test"></textarea>
<script>
tinymce.init(
selector: 'textarea#test',
height: 500,
menubar: false,
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar: 'undo redo | formatselect | ' +
'bold italic backcolor | alignleft aligncenter ' +
'alignright alignjustify | bullist numlist outdent indent | ' +
'removeformat | help',
);
</script>
</body>
</html>
这就是我的小部件:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class RichTextEditor extends StatefulWidget
final String html;
const RichTextEditor(
this.html: '',
);
@override
RichTextEditorState createState() => RichTextEditorState();
class RichTextEditorState extends State<RichTextEditor>
WebViewController _webViewController;
@override
Widget build(BuildContext context)
final String source = Uri.dataFromString(
widget.html,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8'),
).toString();
return Container(
child: Material(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.of(context).pop(),
),
],
mainAxisAlignment: MainAxisAlignment.end,
),
Expanded(
child: WebView(
initialUrl: source,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller)
_webViewController = controller;
_webViewController.loadUrl(source);
,
),
),
],
),
),
padding: EdgeInsets.all(10.0),
);
@override
void initState()
super.initState();
我在控制台中得到以下日志:
D/cr_Ime (30910): [InputMethodManagerWrapper.java:30] Constructor
W/cr_AwContents(30910): onDetachedFromWindow called when already detached. Ignoring
D/cr_Ime (30910): [InputMethodManagerWrapper.java:59] isActive: false
I/cr_Ime (30910): ImeThread is not enabled.
D/EGL_emulation(30910): eglMakeCurrent: 0x8a0f4ca0: ver 2 0 (tinfo 0x8976d190)
W/cr_BindingManager(30910): Cannot call determinedVisibility() - never saw a connection for the pid: 30910
D/cr_Ime (30910): [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime (30910): [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
D/EGL_emulation(30910): eglMakeCurrent: 0xb1e05240: ver 2 0 (tinfo 0xb1e03310)
W/cr_BindingManager(30910): Cannot call determinedVisibility() - never saw a connection for the pid: 30910
D/cr_Ime (30910): [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime (30910): [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
I/art (30910): Background sticky concurrent mark sweep GC freed 12(424B) AllocSpace objects, 0(0B) LOS objects, 0% free, 22MB/22MB, paused 10.801ms total 19.097ms
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
I/chromium(30910): [INFO:CONSOLE(9)] "Failed to initialize the editor as the document is not in standards mode. TinyMCE requires standards mode.", source: https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.2.1/tinymce.min.js (9)
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
W/art (30910): Attempt to remove non-JNI local reference, dumping thread
任何帮助将不胜感激。谢谢!
【问题讨论】:
【参考方案1】:要使 TinyMCE
正常工作,您还需要在 HTML 的开头添加 <!DOCTYPE html>
(请参阅 https://community.tiny.cloud/communityQuestion?id=9064N000000MvpyQAC)。
你也可以试试我的插件flutter_inappwebview,如果它不适用于webview_flutter
。
它是一个 Flutter 插件,可让您添加内联 WebView 或打开应用内浏览器窗口,并提供大量事件、方法和选项来控制 WebView。
这是一个使用initialData: InAppWebViewInitialData()
属性在 WebView 中注入初始 HTML 字符串的示例:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async
WidgetsFlutterBinding.ensureInitialized();
runApp(new MyApp());
class MyApp extends StatefulWidget
@override
_MyAppState createState() => new _MyAppState();
class _MyAppState extends State<MyApp>
InAppWebViewController webView;
@override
void initState()
super.initState();
@override
void dispose()
super.dispose();
@override
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('InAppWebView Example'),
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: InAppWebView(
initialData: InAppWebViewInitialData(data: """
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.2.1/tinymce.min.js"></script>
</head>
<body>
<textarea id="test"></textarea>
<script>
tinymce.init(
selector: 'textarea#test',
height: 500,
menubar: false,
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar: 'undo redo | formatselect | ' +
'bold italic backcolor | alignleft aligncenter ' +
'alignright alignjustify | bullist numlist outdent indent | ' +
'removeformat | help',
);
</script>
</body>
</html>
"""),
initialHeaders: ,
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
),
android: AndroidInAppWebViewOptions(
builtInZoomControls: true
)
),
onWebViewCreated: (InAppWebViewController controller)
webView = controller;
,
onLoadStart: (InAppWebViewController controller, String url)
,
onLoadStop: (InAppWebViewController controller, String url)
))
])),
),
);
截图:
【讨论】:
我正在尝试在 Flutter Web 中使用您的解决方案,但是使用上面的代码我得到以下错误:1)onLoadStart 和 onLoadStop 函数的第二个参数是 Uri 而不是 String 2)在浏览器中,我得到“flutter_inappwebview 插件尚不支持targetPlatform.windows” Ciao Francesco,如您所见,这个问题很老了,与此同时,插件也在进化。此示例适用于旧版本 4.0.0+4。对于第一个错误:您可以从参数中删除类型或将其更改为Uri
(通常,URL 现在有Uri
输入新版本5!)。对于第二个错误:是的,该插件目前仅支持 Android 和 ios。我还会添加对 MacOS、Linux 和 Windows 的支持,但这需要很多时间以上是关于有没有办法在 Flutter WebView 中导入外部脚本的主要内容,如果未能解决你的问题,请参考以下文章
在flutter webview中播放视频时,有没有办法打开像MX播放器这样的外部视频播放器? [关闭]
webview_flutter 违反了内容安全政策,有啥解决办法吗?
有没有办法在没有 Internet 连接的情况下在 webview 中加载网站?
Flutter Webview - 在浏览器或窗口中打开外部链接
flutter 安卓webview 无法加载http解决方案net::ERR_CLEARTEXT_NOT_PERMITTED