Как отправить изображение (файл) в GET-запросе?

«Как отправить изображение (файл) в GET-запросе?» — вопрос из категории Сети, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Согласно спецификации HTTP, метод GET не предназначен для передачи данных в теле запроса, включая файлы. Его цель — получение (fetch) ресурса, а параметры передаются только в URL (как query-параметры).

Неправильные подходы (которые не стоит использовать):

  1. Попытка отправить multipart/form-data с GET — большинство серверов и клиентских библиотек (включая Dart's http или Dio) этого не поддерживают.
  2. Кодирование файла в base64 и передача как query-параметра — быстро упрётся в ограничение длины URL (обычно 2-8 КБ).

Правильные архитектурные решения для передачи файлов:

1. Использование метода POST (или PUT) с multipart/form-data:

import 'package:dio/dio.dart';
import 'package:image_picker/image_picker.dart';

Future<void> uploadImage(XFile imageFile) async {
  final dio = Dio();

  FormData formData = FormData.fromMap({
    'image': await MultipartFile.fromFile(
      imageFile.path,
      filename: 'avatar.jpg',
    ),
    'userId': '12345',
  });

  final response = await dio.post(
    '/api/upload',
    data: formData,
  );
  print('Изображение загружено: ${response.data}');
}

2. Отдельный эндпоинт для загрузки, а GET — только для получения метаданных или ссылки:

// Шаг 1: Загружаем файл POST-запросом
final uploadResponse = await dio.post('/api/images', data: formData);
final String imageId = uploadResponse.data['id']; // Сервер возвращает ID

// Шаг 2: Получаем метаданные или ссылку на файл через GET
final metaResponse = await dio.get('/api/images/$imageId');
// Сервер может вернуть JSON с URL для скачивания, размерами и т.д.

3. Загрузка по предварительно сгенерированной signed-ссылке (как в AWS S3):

// 1. Запрашиваем у сервера временную ссылку для загрузки (GET /api/upload-url)
// 2. Сервер возвращает signed URL для прямого PUT-запроса в облачное хранилище
// 3. Клиент загружает файл напрямую по этой ссылке методом PUT

Таким образом, передача файла всегда происходит через POST/PUT. GET-запросы используются для получения уже загруженных данных по их идентификатору.