APP : Developed with Flutter
Web: Develop with Flutter
Use the webview_flutter plugin to load web pages in app.
Now the web page wants to communicate with the APP.
It is possible to use JavaScript methods to interact with flutter.
JavaScript code
function toast() {
Toast.postMessage("message from web page");
}
Flutter APP code
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toast',
onMessageReceived: (JavascriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
The above method is possible.
But now Flutter web tries to interact with Flutter APP and fails, code show as below
Flutter web code
void toast() {
html.window.postMessage("message from web page", "Toast");
}
Flutter APP code same as above.
The error message is as follows
I/chromium(25735): [INFO:CONSOLE(14560)] "SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin 'Toast' in a call to 'postMessage'."
Is there something wrong with my calling method?
There's a way, but it doesn't feel good.
Define a JavaScript file in the web
directory, here called toast.js
. This file defines the methods to communicate with Dart.
function makeToast(msg) {
Toast.postMessage(msg);
}
Import toast.js
in index.html
in the web directory
<head>
// ...
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
<!-- new line -->
<script src="toast.js"></script>
</head>
Go back to the Flutter project and create a dart file in the lib
directory, called js_channel.dart
here, declare a method in this file for Dart to call JavaScript methods
import 'package:js/js.dart';
@JS('makeToast')
external void makeToast(String msg);
Call makeToast
method
void toast() {
makeToast("msg from flutter web")
}
The above steps are all done in the flutter web project.
Next, you need to use the webview in the Flutter native (android or ios) project to load the web page built by the Flutter web project, and then listen to the message sent by the Toast object in the webview.
Here I am using the webview_flutter plugin
Widget _buildWebView() {
return WebView(
debuggingEnabled: true,
initialUrl: "your web url",
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: <JavascriptChannel>{
JavascriptChannel(
name: 'Toast',
onMessageReceived: (JavascriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
},
),
},
),
}