文章:
Flutter WebView与JS交互简易指南
使用官方的库:webview_flutter
学习可参考官方demo:官方库以及demo的Github地址
帖子:
https://stackoverflow.com/questions/53689662/flutter-webview-two-way-communication
补充一
- 在iOS上加载http网页的(https不需要),需要在iOS-info.plist中添加http支持,添加如下到info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
- 同时官方文档里还让在info.plist中添加如下:
<key>io.flutter.embedded_views_preview</key>
<true/>
补充二
如上文所说:
方法一:使用路由委托navigationDelegate拦截url
在navigationDelegate中进行拦截
navigationDelegate: (NavigationRequest navigation) {
String url = Uri.decodeFull(navigation.url);
logPrint(url, message: "js调用flutter传递的内容:");
if (url.startsWith("moka://")) {
// 拦截后执行操作
List<String> queryList = url.split("?");
if (queryList.length > 1) {
String query = queryList[1];
logPrint(json.decode(query), message: "query");
JsActionModel jsActionModel =
JsActionModel.fromJson(json.decode(query));
_iosAction(jsActionModel);
}
// {"method":"toLogin", "param": "rate", "page": "pagevalue"}
logPrint('blocking navigation to $navigation');
return NavigationDecision.prevent; // 阻止路由替换
}
logPrint('allow navigation to $navigation');
return NavigationDecision.navigate; // 允许路由替换
},
// JS调用Flutter:使用路由委托navigationDelegate拦截url
void _iosAction(JsActionModel model) {
if (model.page != null && model.page.length != 0) {
// 跳转页面
logPrint(model.page, message: "model.page");
return;
}
if (model.method != null && model.method.length != 0) {
logPrint(model.method, message: "model.method");
// 执行对应的方法
if (model.method == "toLogin") {
// 调用登录
Navigator.of(context)
.push(CupertinoPageRoute(builder: (BuildContext context) {
return new LoginPage();
}));
}
if (model.method == "") {
// 调用其他方法
}
return;
}
}
方法二:使用javascriptChannels发送消息
缺点:js调用的方法好像得是postMessage
(这里我不太确定,有知道的麻烦告知,多谢)
其中js中的方法调用是:
WebViewJavascriptBridge.postMessage('Hello World');
javascriptChannels: <JavascriptChannel>[
// 使用javascriptChannels发送消息
_callPageJavaScriptChannel(context),
].toSet(),
// js直接调用方法打开页面
JavascriptChannel _callPageJavaScriptChannel(BuildContext context) {
return JavascriptChannel(
name: "WebViewJavascriptBridge",
onMessageReceived: (JavascriptMessage message) {
logPrint('${message.message}');
callPage(message.message);
},
);
}
- 其中controller调用evaluateJavascript,可使用以下方法来调用js
onPageFinished: (String url) {
_controller.future.then((controller) {
controller
.evaluateJavascript('hideHeader();')
.then((result) {});
});
},