Open rajeshzmoke opened 4 years ago
I had the same bug and I found how it happens, it happens when the onCreateWindow.url
is 'about:blank' if you do
onCreateWindow: (controller, onCreateWindow) {
controller.loadUrl(url: 'https://www.google.com');
},
the error disappear, not sure now I can load the blank tab yet then though.
.. open a new window/ tab ..
You need yourself to implement webview tab features, InAppWebView
widget is not a browser, but a WebView. The onCreateWindow
is just an event that intercepts this intent. If you want to open a new InAppWebView
widget, you need to implement it yourself, like creating a browser app.
@alex-min I cannot reproduce your error. This example is working fine when I click on <a target="_blank" href="about:blank">TEST TEST TEST</a>
:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: InAppWebViewPage()
);
}
}
class InAppWebViewPage extends StatefulWidget {
@override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController _webViewController;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InAppWebView")
),
body: SafeArea(
child: Column(children: <Widget>[
Expanded(
child: Container(
margin: const EdgeInsets.all(20.0),
decoration:
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
child: InAppWebView(
initialData: InAppWebViewInitialData(
data: """
<!DOCTYPE html>
<html lang="en">
<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 class="text-center">
<a target="_blank" href="about:blank">TEST TEST TEST</a>
</body>
</html>
"""
),
initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useShouldOverrideUrlLoading: true,
),
android: AndroidInAppWebViewOptions(
supportMultipleWindows: true
)
),
onWebViewCreated: (InAppWebViewController controller) {
print("onWebViewCreated");
_webViewController = controller;
},
onCreateWindow: (controller, onCreateWindowRequest) async {
print("onCreateWindow called");
controller.loadUrl(url: onCreateWindowRequest.url);
},
onLoadStart: (InAppWebViewController controller, String url) {
print("onLoadStart $url");
},
onLoadStop: (InAppWebViewController controller, String url) async {
print("onLoadStop $url");
},
),
),
),
]))
);
}
}
Could you share the URL that contains the link of your blank tab? @rajeshzmoke if you can, you too, otherwise I cannot debug this error.
Also, this error happens on all devices and in all cases? Thanks
After more investigation, it does happen from some urls and not others, I'm not sure what causes it, google.com is totally fine but I was trying to integrate plaid.com and the plaid window is a 100% crash. You can try to navigate to this url with loadUrl: https://cdn.plaid.com/link/v2/stable/sandbox-oauth-login.html?redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&state=eyJvYXV0aF9zdGF0ZV9pZCI6Ijk0ZjJhN2RkLTVlYzMtNDYxNC1hZWQ4LWI0MDFiZjgyZWE5NiIsInVzZV9vYXV0aF9jYWxsYmFjayI6ZmFsc2UsInBsYWlkX2VudiI6InNhbmRib3gifQ
. So I'm not sure what js api causes it, difficult to say.
let me know if you can reproduce as well
@alex-min This is working fine:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: InAppWebViewPage()
);
}
}
class InAppWebViewPage extends StatefulWidget {
@override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController _webViewController;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InAppWebView")
),
body: SafeArea(
child: Column(children: <Widget>[
Expanded(
child: Container(
child: InAppWebView(
initialData: InAppWebViewInitialData(
data: """
<!DOCTYPE html>
<html lang="en">
<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 class="text-center">
<a target="_blank" href="https://cdn.plaid.com/link/v2/stable/sandbox-oauth-login.html?redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&state=eyJvYXV0aF9zdGF0ZV9pZCI6Ijk0ZjJhN2RkLTVlYzMtNDYxNC1hZWQ4LWI0MDFiZjgyZWE5NiIsInVzZV9vYXV0aF9jYWxsYmFjayI6ZmFsc2UsInBsYWlkX2VudiI6InNhbmRib3gifQ">TEST TEST TEST</a>
</body>
</html>
"""
),
initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useShouldOverrideUrlLoading: true,
),
android: AndroidInAppWebViewOptions(
supportMultipleWindows: true
)
),
onWebViewCreated: (InAppWebViewController controller) {
print("onWebViewCreated");
_webViewController = controller;
},
onCreateWindow: (controller, onCreateWindowRequest) async {
print("onCreateWindow called with URL ${onCreateWindowRequest.url}");
controller.loadUrl(url: onCreateWindowRequest.url);
},
onLoadStart: (InAppWebViewController controller, String url) {
print("onLoadStart $url");
},
onLoadStop: (InAppWebViewController controller, String url) async {
print("onLoadStop $url");
},
),
),
),
]))
);
}
}
That also works for me, I will try to reduce it to a minimum test case
here you go, if you replace the html by that you can trigger it
InAppWebViewInitialData(data: """
<!DOCTYPE html>
<html lang="en">
<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 class="text-center">
<a id="test">TEST TEST TEST</a>
<script>
document.getElementById('test').onclick = () => {
let w = window.open('https://cdn.plaid.com/link/v2/stable/sandbox-oauth-login.html?redirect_uri=https%3A%2F%2Fcdn.plaid.com%2Flink%2Fv2%2Fstable%2Foauth.html&state=eyJvYXV0aF9zdGF0ZV9pZCI6Ijk0ZjJhN2RkLTVlYzMtNDYxNC1hZWQ4LWI0MDFiZjgyZWE5NiIsInVzZV9vYXV0aF9jYWxsYmFjayI6ZmFsc2UsInBsYWlkX2VudiI6InNhbmRib3gifQ', 'test');
w.focus();
setInterval(() => {
console.log(w.closed);
console.log(w.opener);
}, 1000);
}
</script>
</body>
</html>
""")
I tried it but I didn't have any error. Instead, I received about:blank
as URL of onCreateWindow
event. Using javascript is a little bit problematic.
So, I'm thinking to re-implement the onCreateWindow
event in another way, adding also the onCloseWindow
event (in android, for example, is the https://developer.android.com/reference/android/webkit/WebChromeClient#onCloseWindow(android.webkit.WebView) event). I need to think about how to make it work in Flutter.
Ah interesting, there's maybe something different on my config, this sample triggers 100% of the time the crash on my end. Actually it seems to be more the .closed & .opener which seems to cause problems for me rather than the window.open(), I've added them because it's what plaid.com does in a setInterval (I've spied with object proxies to find that) and that what I think makes the page crash.
here is my flutter doctor if it can help you:
[✓] Flutter (Channel stable, v1.17.4, on Linux, locale fr_FR.UTF-8)
• Flutter version 1.17.4 at /usr/share/flutter
• Framework revision 1ad9baa8b9 (il y a 6 jours), 2020-06-17 14:41:16 -0700
• Engine revision ee76268252
• Dart version 2.8.4
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
• Android SDK at /home/alex/Android/Sdk
• Platform android-30, build-tools 29.0.2
• ANDROID_HOME = /home/alex/Android/Sdk
• Java binary at: /home/alex/android/android-studio/jre/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
• All Android licenses accepted.
[✓] Android Studio (version 4.0)
• Android Studio at /home/alex/android/android-studio
• Flutter plugin version 46.0.2
• Dart plugin version 193.7361
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
[✓] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)
• No issues found!
Let me know if I can help you with any command, the traceback I have is identical of the one of @rajeshzmoke
@alex-min @pichillilorenzo so what i've found is that when debugging in an android emulator i get an actual url in onCreateWindow
callback but when i run it in release mode, i get an about blank
.
also i know for a fact that the webapp which i open in webview does a window.post()
to the new tab that is being opened.
We have stopped fixing this issue on flutter side as i couldnt find any feasible library or a way to fix this and instead make the new url make api call instead of using window.post()
in the webapp, which is a reasonable workaround for us
For example, at this moment, the Android onCreateWindow
implementation can be found here:
https://github.com/pichillilorenzo/flutter_inappwebview/blob/9fda80ae157ab61a813f9065a61bf851ebd9eba8/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java#L476
If needed, I create a temp WebView to get the URL and then I destroy it.
Instead, I need to change it in order to be able to create an InAppWebView
instance from the Flutter side, otherwise, the created WebView will result in an always closed window.
Also, this should be done on iOS.
I need to think about it and how to do that.
Environment
flutter_inappwebview: ^3.3.0+3
Description
App crashing when clicking on a link that opens in a new tab, Expected behavior: loading inital url and then when clicking on a button in the webview open a new new window/ tab
Current behavior: loading initial url and when clicking on a button in the webview crashes the app
Steps to reproduce
Stacktrace/Logcat