Внедрение JavaScript в Flutter WebView — Полное руководство
FlutterPulseЭта статья переведена специально для канала FlutterPulse. В этом канале вы найдёте много интересных вещей, связанных с Flutter. Не забывайте подписываться! 🚀

Веб-представление Flutter — webview_flutter мощное для встраивания веб-контента, но иногда вам нужно больше, чем просто загрузка страницы.
Что если вы хотите:
- Захватить значения формы ввода (например, имя пользователя или электронную почту)?
- Динамически изменять элементы DOM?
- Добавить пользовательские слушатели кликов?
- Общаться между веб-страницей и Flutter?
Именно здесь появляется внедрение JavaScript.
В этом руководстве мы научимся, как внедрить JavaScript в WebView, захватить значения и отправить их обратно в Flutter.
Добавление webview_flutter
Чтобы начать, добавьте пакет в свой pubspec.yaml:
dependencies:
flutter:
sdk: flutter
webview_flutter: ^4.8.0
webview_flutter | Пакет Flutter(Всегда проверяйте pub.dev на наличие последней версии.)
Плагин Flutter, который предоставляет виджет WebView, поддерживаемый системой webview.
pub.dev
️ Настройка WebView
Сначала давайте настроим WebView с включенным неограниченным JavaScript:
final WebViewController controller =
WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
'FormChannel',
onMessageReceived: (JavaScriptMessage message) {
debugPrint("Перехвачено из WebView: ${message.message}");
},
)
..loadRequest(Uri.parse("https://example.com/login"));
Здесь мы создали канал JavaScript (FormChannel), который действует как "мост" между JavaScript и Flutter.
Внедрение JavaScript
Теперь давайте внедрим некоторый JavaScript, когда страница завершит загрузку:
Future<void> _injectCustomHook() async {
await _controller.runJavaScript('''
(function() {
const loginButton = document.querySelector('button[type="submit"]');
if (loginButton) {
loginButton.addEventListener('click', function() {
const input = document.getElementById('username')?.value || '';
FormChannel.postMessage(input);
});
}
})();
''');
}Что делает этот код
- Находит кнопку входа внутри WebView.
- Слушает событие клика.
- Читает поле ввода с идентификатором username.
- Отправляет его обратно в Flutter, используя FormChannel.
Получение данных в Flutter
Данные поступают обратно во Flutter через канал JavaScript:
..addJavaScriptChannel(
'FormChannel',
onMessageReceived: (JavaScriptMessage message) {
debugPrint("Пользователь ввел: ${message.message}");
// Используйте значение в вашем приложении
},
)
Если пользователь вводит hello@example.com в веб-форме, Flutter выводит следующее в консоли:
Пользователь ввел: hello@example.com
🚀 Почему инъекция JavaScript мощна
С помощью инъекции JS вы можете:
- Перехватить значения ввода перед их отправкой.
- Автоматически заполнить формы.
- Скрыть или переоформить нежелательные элементы.
- Добавить дополнительную функциональность к существующим веб-страницам.
Пример: Скрыть баннер внутри WebView
await _controller.runJavaScript('''
document.querySelector('.ads-banner')?.style.display = 'none';
''');🧩 Окончательный справочный код
Вот полный справочный код, объединяющий настройку WebView, инъекцию JavaScript и захват данных:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewExample extends StatefulWidget {
const WebViewExample({super.key});
@override
State<WebViewExample> createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
final params = const PlatformWebViewControllerCreationParams();
final controller = WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
NavigationDelegate(
onPageFinished: (url) {
_injectCustomHook();
},
),
)
..addJavaScriptChannel(
'FormChannel',
onMessageReceived: (JavaScriptMessage message) {
debugPrint("Перехвачено из WebView: ${message.message}");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Пользователь ввел: ${message.message}")),
);
},
)
..loadRequest(Uri.parse("https://example.com/login"));
_controller = controller;
}
Future<void> _injectCustomHook() async {
await _controller.runJavaScript('''
(function() {
const loginButton = document.querySelector('button[type="submit"]');
if (loginButton) {
loginButton.addEventListener('click', function() {
const input = document.getElementById('username')?.value || '';
FormChannel.postMessage(input);
});
}
})();
''');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Инъекция JS в WebView")),
body: WebViewWidget(controller: _controller),
);
}
}
🔄 Альтернативы
Хотя webview_flutter поддерживает базовую инъекцию JS, другие пакеты предлагают больше:
- flutter_inappwebview
Плагин Flutter, который позволяет добавить встроенный веб-просмотр, использовать безголовый веб-просмотр и открывать встроенный браузер…
pub.dev
Расширенная инъекция JS, перехват сетевых запросов, управление cookie и лучший выбор, если вам нужен глубокий контроль над страницей.
2. flutter_web_auth_2
flutter_web_auth_2 | Пакет FlutterПлагин Flutter для аутентификации пользователя с помощью веб-сервиса.
pub.dev
Открывает системный браузер вместо инъекции JS и отлично подходит для потоков OAuth.
Лучшие практики
- Всегда очищайте и проверяйте данные, полученные из внедренного JavaScript.
- Тестируйте на нескольких платформах (Android и iOS ведут себя немного по-разному).
- Избегайте чрезмерного использования внедрения JS — используйте его только тогда, когда родные API Flutter или API бэкенда не могут достичь того же.
Заключение
Внедрение JavaScript — это как дать вашему Flutter WebView суперспособности. В следующий раз, когда вы встраиваете веб-страницу в Flutter, не просто отображайте ее — внедряйте свою логику и делайте ее умнее!