Charles Proxy не видит запросы Flutter-приложения: как это исправить за 3 шага
Charles Proxy не показывает запросы Flutter-приложения, потому что Dart по умолчанию игнорирует системный прокси телефона. Чтобы увидеть трафик, укажите адрес Charles прямо в HttpClient debug-сборки, добавьте хост в SSL Proxying и установите корневой сертификат Charles на устройство. Release-сборка при этом остаётся без прокси.
Почему Charles Proxy не видит запросы Flutter-приложения 🔍
Четверг, вечер. В понедельник релиз приложения для торговых представителей. Тестировщик подключил телефон к Charles на ноутбуке, и страницы из браузера честно ложатся в список запросов. Но стоит открыть экран «Заказы» во Flutter-приложении, как Charles молчит, а на телефоне бесконечно крутится индикатор загрузки.
Причина в устройстве Flutter. Нативные приложения Android и iOS читают настройки прокси у системы. Flutter ходит в сеть через собственный сетевой слой Dart, а его HttpClient по умолчанию ищет прокси в переменных окружения, которых на телефоне нет. Системный прокси для приложения не существует, поэтому трафик идёт напрямую, мимо Charles.
Ставка тут простая. Без тела запроса и ответа никто не скажет, где сломался заказ: в приложении, на сервере или при передаче в 1С. Баг уходит разработчику с описанием «не работает», тот не воспроизводит его на своей машине, и задача несколько раз ходит между отделами. Релиз сдвигается, а представители в понедельник записывают заказы в блокнот.
Как исправить: настроить Charles Proxy для Flutter за три шага
Шаг 1. Charles и телефон в одной сети
Запустите Charles на ноутбуке. Порт прокси по умолчанию 8888, он меняется в Proxy → Proxy Settings. IP ноутбука в локальной сети показывает пункт Help → Local IP Address. Телефон и ноутбук должны находиться в одной подсети. Для эмулятора Android адрес хоста 10.0.2.2, для симулятора iOS подойдёт localhost.
Если тестируете в гостевом Wi-Fi офиса, проверьте изоляцию клиентов. Во многих гостевых сетях устройства друг друга не видят, и телефон не достучится до порта 8888.
Шаг 2. Прокси внутри приложения
Этот шаг пропускают чаще всего. В debug-сборке приложению нужно явно сказать, куда слать трафик: задать свойству findProxy у HttpClient значение «PROXY 192.168.1.10:8888», где адрес — IP ноутбука. Обычно это делают один раз, через HttpOverrides.global в функции main().
Адрес не стоит зашивать в код. Передавайте его при сборке ключом --dart-define=PROXY=192.168.1.10:8888 и читайте через String.fromEnvironment. Без параметра приложение ходит в сеть как обычно.
Шаг 3. Сертификат и SSL Proxying
Без сертификата Charles покажет хосты, но тела запросов останутся зашифрованными. На телефоне, который уже работает через прокси, откройте в браузере chls.pro/ssl и установите профиль. На iOS его дополнительно включают вручную: Настройки → Основные → Об этом устройстве → Доверие сертификатам. Затем в Charles откройте Proxy → SSL Proxying Settings и добавьте хост вашего API с портом 443.
На Android 7 и новее приложения по умолчанию не доверяют сертификатам, которые пользователь поставил сам, а Dart проверяет цепочку собственным слоем. Поэтому в debug-сборке передайте корневой сертификат Charles в SecurityContext. Запасной вариант — badCertificateCallback, но только под условием kDebugMode и только для хоста тестового API.
Что делать, если ошибка повторяется
Если трафик так и не появился, найдите свой случай в таблице.
| Симптом | Причина | Что делать |
|---|---|---|
| Charles пуст, приложение не грузит данные | Прокси не задан в приложении, трафик идёт напрямую | Задать findProxy в debug-сборке, проверить IP ноутбука и порт 8888 |
| Хосты видны, тела запросов нечитаемы | Хост не добавлен в SSL Proxying или сертификат не включён в доверенные | Добавить хост с портом 443, на iOS включить доверие сертификату |
| Ошибка сертификата или handshake failed в приложении | Приложение не принимает сертификат Charles или включён pinning | Передать сертификат в SecurityContext, для pinning собрать тестовый вариант без него |
| Телефон не соединяется с прокси | Гостевая сеть изолирует клиентов или порт 8888 закрыт брандмауэром | Перейти в рабочую сеть, открыть порт на ноутбуке |
| Charles закрывается примерно через 30 минут | Пробный режим без лицензии | Зарегистрировать лицензию Charles |
Отдельная история с certificate pinning. Приложение сверяет сертификат сервера с зашитым отпечатком, Charles подставляет свой, и соединение обрывается. Отключать пиннинг в боевой сборке нельзя. Поэтому делают тестовую конфигурацию, где пиннинг выключен, а в release он всегда включён.
Что тестировщик находит в Charles быстрее, чем в логах 🧪
Когда трафик пошёл, Charles быстро показывает то, чего в логах приложения не видно. Типичные находки:
- ✓запрос ушёл с просроченным токеном, сервер ответил 401, а приложение молча показало пустой список;
- ✓в теле заказа количество пришло строкой вместо числа, и 1С отклонила документ;
- ✓экран «Каталог» при каждом открытии шлёт один и тот же запрос несколько раз подряд;
- ✓сервер вернул 500 с текстом ошибки из 1С, а пользователь увидел только «Что-то пошло не так».
Два инструмента Charles экономят больше всего времени. Breakpoints останавливают запрос или ответ и дают поправить его вручную: так проверяют, как приложение ведёт себя на ответе 500 или на пустом списке, не трогая сервер. Throttle сужает канал и добавляет задержку, чтобы увидеть, что происходит у торгового представителя на складе с плохим приёмом.
Как предотвратить: прокси как часть сборки, а не ручной ритуал
Ручная настройка ломается при каждой смене ноутбука, сети или сборки. Надёжнее вшить её в процесс разработки:
- ✓в проекте заведены варианты сборки (flavors) dev, stage и prod, а прокси и ослабленная проверка сертификатов существуют только в dev и stage;
- ✓адрес прокси приходит через dart-define, в репозитории его нет;
- ✓CI-проверка роняет release-сборку, если в ней остался findProxy или badCertificateCallback;
- ✓в репозитории лежит инструкция на одну страницу для тестировщиков: порт, где взять сертификат, как включить доверие на iOS.
Третий пункт не формальность. Забытый badCertificateCallback в release отключает проверку сертификата сервера, и трафик в публичной сети может подменить любой желающий.
Что делать с персональными данными в дампах
Сессии Charles сохраняют всё, что прошло через приложение: телефоны клиентов, имена, суммы заказов. Если тестировать на боевых данных, файл сессии становится носителем персональных данных, и на его хранение и передачу распространяется 152-ФЗ. Поэтому тестовый контур наполняют обезличенными данными, а файлы сессий не отправляют в Telegram-чаты и не прикладывают к задачам без очистки.
Как мы настраиваем тестирование во Flutter-проектах для заказчиков 🛠
Эту связку мы закладываем в проект с первого спринта, а не чиним перед релизом. В разработке мобильных приложений на Flutter мы передаём заказчику репозиторий с готовыми вариантами сборки, параметром прокси через dart-define и одностраничной инструкцией для тестировщиков. Тестировщик заказчика ставит Charles, вводит IP ноутбука и сразу видит запросы.
Для приложений, которые обмениваются данными с учётной системой, мы отдельно разбираем цепочку «приложение → сервер → 1С». При интеграции приложения с 1С Charles быстро показывает звено, где ломается заказ: приложение отправило неверное тело, сервер вернул ошибку или 1С не приняла документ. Так устроены и B2B-приложения с 1С для торговых представителей и дилеров: заказ из телефона попадает прямо в учёт.
Чем это отличается от привычной истории «разработчик сдал сборку, дальше сами»: тестовая сборка с прокси и стенд с обменом 1С готовы к началу тестирования, а не появляются после первого «у меня не воспроизводится». Тестировщикам не нужно просить разработчика пересобрать приложение ради одного запроса.
Разработка мобильного приложения у нас стоит от 500 000 ₽. Итог зависит от числа экранов и объёма интеграции с 1С, а ориентиры по остальным услугам собраны на странице цен и тарифов. Если приложение уже написано и тестировщики упираются в тишину в Charles, опишите стек: подскажем, какие правки нужны в сборке.
❓ Частые вопросы
Почему Charles не показывает трафик Flutter-приложения, хотя браузер на телефоне виден?
Dart по умолчанию не читает системный прокси телефона, поэтому Flutter-приложение ходит в сеть напрямую. Браузер использует настройки системы и попадает в Charles. Чтобы увидеть трафик приложения, задайте адрес Charles в findProxy у HttpClient в debug-сборке, например через HttpOverrides.global, и перезапустите приложение.
Как увидеть HTTPS-запросы Flutter-приложения в Charles?
Установите корневой сертификат Charles на устройство через chls.pro/ssl, на iOS включите ему доверие в настройках, добавьте хост API с портом 443 в SSL Proxying Settings. На Android в debug-сборке дополнительно передайте сертификат в SecurityContext приложения, потому что Dart не всегда принимает пользовательские сертификаты.
Можно ли оставить настройку прокси в release-сборке?
Нельзя. Прокси и ослабленная проверка сертификатов нужны только в debug и тестовых сборках. Забытый badCertificateCallback в release отключает проверку сервера, и трафик в публичной сети может подменить посторонний. Разделите варианты сборки и добавьте в CI проверку, которая падает при таких настройках в release.
Что делать, если приложение использует certificate pinning?
Для тестов соберите отдельный вариант приложения с выключенным пиннингом: Charles подставляет свой сертификат, и пиннинг рвёт соединение. В release пиннинг остаётся включённым. Так тестировщики читают трафик, а боевая сборка защищена от подмены сертификата. Заведите это отдельным вариантом сборки (flavor) с понятным названием, чтобы никто не перепутал его с релизной.
Сколько стоит разработка мобильного приложения с интеграцией 1С?
Разработка мобильного приложения на ukved.ru стоит от 500 000 ₽. Итоговая цена зависит от числа экранов, платформ и объёма обмена с 1С. Тестовые сборки с настроенным прокси и стенд для тестировщиков закладываем в проект с первого этапа. Точную оценку даём после разбора требований.
Или позвоните: +7 906 045-28-27 — в рабочее время с 9:00 до 19:00
Остались вопросы? Нужна помощь?
Менеджеры компании с радостью ответят на ваши вопросы, произведут расчет стоимости услуг и подготовят индивидуальное коммерческое предложение.
Бесплатная консультация

