I am trying to load my website content in my flutter application.
I have a link https://dev.demo.hello.example.com/id/4
I have tried using flutter_webview_plugin & webview_flutter both plugins but on both plugins i am getting below error :
WF: === Starting WebFilter logging for process Runner
WF: _userSettingsForUser mobile: {
filterBlacklist = (
);
filterWhitelist = (
);
restrictWeb = 1;
useContentFilter = 0;
useContentFilterOverrides = 0;
whitelistEnabled = 0;
}
WF: _WebFilterIsActive returning: NO
I have also tried mentioned ATS related things in info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
But still facing the same issue. I have https in my link.
Is there any work around ?
In my case, I was setting a navigationDelegate to prevent all further navigation :
WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (navigation) => navigation.url == url ? NavigationDecision.navigate : NavigationDecision.prevent,
),
It works fine on Android, the initialUrl gets loaded, and any further navigation is blocked.
But on iOS I had to change this code as it was blocking even initialUrl :
WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (navigation) => navigation.url == url ? NavigationDecision.navigate : NavigationDecision.prevent,
),
Yes, just put this code to your navigationDelegate in WebView widget
navigationDelegate: (NavigationRequest request) {
if (request.url == get.url) {
return NavigationDecision.navigate;
}
return NavigationDecision.prevent;
}
it work for me on IoS & Android
Related
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)),
);
},
),
},
),
}
I want to open my index.html in the assets folder but with parameters, I tried to open like this:
initialFile: "assets/index.html?name=foo&lastname=Bar" but it doesn´t work.
return Container(
child: InAppWebView(
//initialFile: "assets/index.html",
initialOptions: inAppWebViewGroupOptions,
initialUrlRequest: URLRequest(
url: Uri.parse("file:///assets/index.html"),
method: 'GET',
body:
Uint8List.fromList(utf8.encode("name=foo&lastname=Bar")),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}),
),
);
}
maybe you can just set WebView cookie to pass paramerters.
You can use In-App Localhost Server.
I want to write an application that makes me register from app and send post request and get response to inappwebview just like exam below
InAppWebView(
initialUrl: widget.initUrls,
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
mediaPlaybackRequiresUserGesture: false,
debuggingEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController c){
_controller = c;
if(staticEmail != null && staticPass != null) {
_controller.postUrl(url: "https://xxxxxxx.com/my-account", postData: utf8.encode(
"email=${staticEmail}&password=${staticPass}&wooc_user_phone=${staticShop}&wooc_user_name=${staticShop}&woocommerce-register-nonce=5d1b626841&_wp_http_referer=/my-account/®ister=Register") )
.whenComplete(() => {print("done")}).catchError((err){print("err : ${err}");
isloading = false;
});
}
},
);
and it login fine.
But when I go to another link or when I close app and login again it ask me to login again i just want to save cookie or session id that doesn't make me login every time
You can make use of the CookieManager of this flutter_inappwebview package to get and set cookies. This is a singleton that the plugin uses, you can access it via:
CookieManager.instance()
I am using webview_flutter.
I currently have a native login page in my app that takes in a user's name and password. I am trying to find a way to automatically fill in the username and password on the specific page in webview and submit the login request.
Tried doing this
webViewController.evaluateJavascript(
'''
var email = document.getElementById("CustomerEmail");
var password = document.getElementById("CustomerPassword");
email.value = "user#gmail.com";
password.value = "test123";
'''
);
but got the following errors:
Error Domain=WKErrorDomain Code=4 "A JavaScript exception occurred" UserInfo={WKJavaScriptExceptionLineNumber=3, WKJavaScriptExceptionMessage=TypeError: null is not an object (evaluating 'email.value = "user#gmail.com"'), WKJavaScriptExceptionColumnNumber=11, WKJavaScriptExceptionSourceURL=undefined, NSLocalizedDescription=A JavaScript exception occurred})
Greatly appreciate any help on this. Thank you.
The code works, I put it in the wrong place.
The code should be placed under onPageFinished. I had it under onWebViewCreated previously.
The following code works correctly.
WebView(
initialUrl: widget.url,
onPageFinished: (_) {
setState(() {
print("loggedin " + loggedIn.toString());
if(loggedIn == false) {
loggedIn = true;
_controller.future
.then((value) =>
value.evaluateJavascript('''
var email = document.getElementById("CustomerEmail");
var password = document.getElementById("CustomerPassword");
email.value = "user#gmail.com";
password.value = "test123";
document.getElementById('customer_login').submit();
'''));
}
});
},
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
I wanted to upload pics through canva from my flutter app that is why I am using the flutter-webview-plugin for the first time and therefore I am not able to solve this issue.
Code for the same is:-
import 'package:flutter/material.dart';
import 'package:kf_drawer/kf_drawer.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
class SettingsPage extends KFDrawerContent {
#override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Center(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
....
],
),
Expanded(
child: Container(
height: 500,
child: WebView(
initialUrl: "https://shree-hari.github.io/laxmi_canva/index.html",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController){
_controller.complete(webViewController);
},
),
),
)
],
),
),
);
}
}
Please Help me to address this issue 🙄.
Google not allow native Flutter Web-Views to initiate OAuth.
For more info read Google Blog
In your case, I can suggest 3 Possible Solutions.
Try to Sign in with Email/Password instead of Google Sign In.
Use url_launcher to redirect the user to the browser.
If you don't want the user to leave your app
then you can use flutter_custom_tabs
this plugin use Chrome Custom Tabs to create a native experience inside the Flutter App.
You can add this userAgent :
WebView(
initialUrl: url,
userAgent: Platform.isIOS ? 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_2 like Mac OS X) AppleWebKit/605.1.15' +
' (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1' :
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) ' +
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36',
...
Use this package, it works like a charm
https://github.com/LinusU/flutter_web_auth
In the background, this plugin uses ASWebAuthenticationSession on iOS 12+ and macOS 10.15+, SFAuthenticationSession on iOS 11, Chrome Custom Tabs on Android and opens a new window on Web.
Your auth flow must land in the scheme you provide in callbackUrlScheme property. Then just parse the callback url and implement you own business logic around signin/signup
import 'package:flutter_web_auth/flutter_web_auth.dart';
// Present the dialog to the user
final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "my-custom-app");
// Extract token from resulting url
final token = Uri.parse(result).queryParameters['token']
https://stackoverflow.com/a/71297966/18723243
Using webview_flutter package you can fix the problem by adding userAgent: 'random', in the web view constructor. So, it will look like this:
WebView(
userAgent: 'random',
)