WebView Flutter localhost: перенаправление 8888 не работает в iOS версии 26.2 с webview_flutter 4.13.0IOS

Программируем под IOS
Ответить
Anonymous
 WebView Flutter localhost: перенаправление 8888 не работает в iOS версии 26.2 с webview_flutter 4.13.0

Сообщение Anonymous »

Я реализую аутентификацию OAuth в своем приложении Flutter, используя webview_flutter: ^4.13.0. Поток OAuth перенаправляется на
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';
класс LoginWebPage расширяет StatefulWidget {
@override
_LoginWebPageState createState() => _LoginWebPageState();

класс _LoginWebPageState расширяет состояние {
late HttpServer сервер;
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()),
);
}
Конфигурация Info.plist
Я пробовал добавить исключения localhost в ios/Runner/Info.plist:
NSAppTransportSecurity

NSAllowsLocalNetworking

NSExceptionDomains

localhost

NSExceptionAllowsInsecureHTTPLoads

NSExceptionPorts

8888


Вывод отладки
Работает (Android/iOS < Версия 26.2):
🔍 Навигация: https://oauth-provider.com/login
🔍 Навигация: http://localhost:8888/callback?code=abc123
✅ Localhost попал в навигацию: http://localhost:8888/callback?code=abc123
Исследование выполнено
  • Обнаружены связанные проблемы GitHub: https://github.com/flutter/flutter/issues/169588,
    https://github.com/flutter/flutter/issues/75808
  • Версия iOS 26.2 (сборка 23C54) специально внесла критические изменения для обработки локального хоста/HTTP в WebKit.
  • Опробованы различные подходы NavigationDecision
  • Попытка использовать оба формата: localhost и 127.0.0.1.
  • Похоже, проблема связана с регрессией, специфичной для iOS версии 26.2.
Результаты тестирования версии
  • ✅ Версия iOS 25.x: работает отлично
  • ✅ Версия iOS 26.0: работает отлично
  • ✔ iOS версии 26.1: работает нормально
  • ❌ iOS версии 26.2 (сборка 23C54): полностью сломана
  • ✅ Android: работает на всех версиях
Вопросы
  • Кто-нибудь сталкивался с этой версией iOS 26.2 (сборка 23C54) конкретное критическое изменение?
  • Есть ли изменения безопасности WebKit для iOS версии 26.2, блокирующие перенаправления локального хоста?
  • Существует ли обходной путь для webview_flutter 4.13.0 в iOS версии 26.2?
  • Должен ли я отправить отчет об ошибке в Apple для регрессии WebKit iOS версии 26.2?
Похоже, это критическое изменение, представленное специально в iOS версии 26.2 сборки 23C54, которое полностью
нарушает обратные вызовы localhost OAuth в приложениях WebView.
Будем очень благодарны за любую помощь или обходные пути!>

Подробнее здесь: https://stackoverflow.com/questions/798 ... 2-with-web
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»