Рубрики
Flutter

Flutter http заголовки

Обычно я в проектах использую стандартную библиотеку http: ^0.12.2. Но недавно я столкнулся с ошибкой при отправке запроса, а точнее заголовка на сервер при использовании во Flutter http запросов.

Проблема заключается в том, что некоторые старые серверы чувствительны к регистру заголовка, например, им передаешь заголовок «Authorization», а пакет преобразует его в «authorization», что вызывает ошибку авторизации на сервере.

Так оказалось и в моем случае, при подключении к API Zadarma.com, их сервер оказался чувствительным в этом плане и ждет точное совпадение регистра.

Ответ сервера в этом случае отрицательный: {«status»:»Not authorized»}.

Для того, чтобы избежать подобной ошибки в заголовке, используйте стандартный класс HttpClient():

HttpClient httpClient = new HttpClient();

Преимущество данного подхода в том, что можно указать классу сохранить регистр при передаче headers.

За это отвечает параметр preserveHeaderCase: true. Ниже пример:

request.headers.set(header, "$key:$sign", preserveHeaderCase: true);

Полный пример, подключение к Zadarma:

var url = (Uri.https('api.zadarma.com', method, params)); 
httpClient = new HttpClient(); 
HttpClientRequest request = await httpClient.getUrl(url);
request.headers.set(header, "$key:$sign", preserveHeaderCase: true);
HttpClientResponse response = await request.close();

Надеюсь, это поможет избежать поиска проблемы с заголовками во Flutter http запросах.

Более подробная работа с API рассматривается на сайте, в серии статей.

Подключение без использования заголовков

Ниже простой пример подключения по http без использования заголовков, если сервер того не требует:

HttpClient().getUrl(Uri.parse('https://www.вашдомен.com'));

Более сложный пример. Так как getUrl возвращает Future объект, то можно ответ использовать при помощи встроенной функции then():

HttpClient client = new HttpClient();
client.getUrl(Uri.parse("http://www.example.com/"))
    .then((HttpClientRequest request) {
      // Здесь размещаются заголовки запроса
      // Дополнительный код
      return request.close();
    })
    .then((HttpClientResponse response) {
      // Здесь работаем с ответом сервера
      ...
    });

В коде вы могли заметить request.close()— это означает закрытие соединения по http.

Как закрыть соединение во Flutter http

HttpClient поддерживает постоянные подключения, а так же кэширует сетевые подключения, чтобы повторно использовать их, когда это необходимо. Это означает, что сетевые соединения могут оставаться открытыми в течение некоторого времени после завершения запроса.

HttpClient httpClient = new HttpClient();
httpClient.close();

Используйте HttpClient.close, чтобы принудительно завершить работу объекта HttpClient и закрыть неактивные сетевые подключения.

HTTPS-соединения

HttpClient может выполнять https запросы (протокол SSL). Вызов getUrl по https будет работать автоматически, если сертификат сервера подписан ssl сертификатом.

Чтобы добавить свой доверенный центр сертификации или отправить сертификат клиента на серверы, просто передайте объект SecurityContext в качестве необязательного аргумента. Необходимые для передачи сертификата параметры безопасности можно установить в объекте SecurityContext.