http://localhost:8888 для обратного вызова, но это не удается только на устройствах iOS версии 26.2. Перенаправление отлично работает
на Android и всех предыдущих версиях iOS.
Среда
- Flutter: последняя стабильная версия
- webview_flutter: 4.13.0
- iOS: версия 26.2 (сборка 23C54) – последняя версия iOS
- Проблема: Localhost обратные вызовы перенаправления не перехватываются только в iOS версии 26.2.
- Пользователь выполняет вход в систему OAuth в WebView
- Поставщик OAuth перенаправляет на http://localhost:8888/callback?code=xyz
- Приложение перехватывает URL-адрес и обрабатывает код аутентификации
Отлично работает: все версии iOS до 26.2, Android
Не работает только на: iOS версии 26.2 (сборка 23C54)
В iOS версии 26.2 перенаправление localhost полностью игнорируется. Ни onNavigationRequest, ни onWebResourceError
не перехватывает URL-адрес.
Реализация кода
Код: Выделить всё
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class LoginWebPage extends StatefulWidget {
@override
_LoginWebPageState createState() => _LoginWebPageState();
}
class _LoginWebPageState extends State {
late HttpServer server;
WebViewController? _webViewController;
final StreamController onCodeListener = StreamController();
@override
void initState() {
super.initState();
_startAuthFlow();
}
Future _startAuthFlow() async {
// Start local server for OAuth callback
server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8888, shared: true);
debugPrint('✅ Server bound to localhost:8888');
_listenForServerResponse(server);
_initializeWebView();
}
void _listenForServerResponse(HttpServer server) async {
server.listen((HttpRequest request) async {
final uri = request.uri;
debugPrint('🎯 Server received: $uri');
request.response
..statusCode = 200
..headers.set('Content-Type', ContentType.html.mimeType);
onCodeListener.add(uri);
});
}
void _initializeWebView() {
_webViewController = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
NavigationDelegate(
onNavigationRequest: (navigationRequest) {
debugPrint('🔍 Navigation: ${navigationRequest.url}');
// Try to catch localhost redirect
if (navigationRequest.url.contains('http://localhost:8888')) {
debugPrint('✅ Localhost caught in navigation: ${navigationRequest.url}');
onCodeListener.add(Uri.parse(navigationRequest.url));
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
onWebResourceError: (WebResourceError error) {
debugPrint('❌ WebResource Error: ${error.url} - ${error.description}');
// Try to catch failed localhost requests
if (error.url != null && error.url!.contains('http://localhost:8888')) {
debugPrint('✅ Localhost caught in error: ${error.url}');
onCodeListener.add(Uri.parse(error.url!));
}
},
onPageStarted: (url) {
debugPrint('📄 Page started: $url');
// Additional attempt to catch localhost
if (url.contains('http://localhost:8888')) {
debugPrint('✅ Localhost caught in page start: $url');
onCodeListener.add(Uri.parse(url));
}
},
),
)
..loadRequest(Uri.parse('https://your-oauth-provider.com/login'));
}
@override
void dispose() {
server.close(force: true);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('OAuth Login')),
body: _webViewController != null
? WebViewWidget(controller: _webViewController!)
: Center(child: CircularProgressIndicator()),
);
}
}
Я пробовал добавить исключения localhost в ios/Runner/Info.plist:
Код: Выделить всё
NSAppTransportSecurity
NSAllowsLocalNetworking
NSExceptionDomains
localhost
NSExceptionAllowsInsecureHTTPLoads
NSExceptionPorts
8888
Работает (Android/iOS
Подробнее здесь: https://stackoverflow.com/questions/798 ... 2-with-web
Мобильная версия