Flutter: http post загрузить картинку

Я использую веб-сервис для обработки изображений, он хорошо работает в Почтальоне:

postman screenshot

Теперь я хочу сделать запрос http в трепетании с Дарт:

import 'package:http/http.dart' as http;

static ocr(File image) async {
    var url = '${API_URL}ocr';
    var bytes = image.readAsBytesSync();

    var response = await http.post(
        url,
        headers:{ "Content-Type":"multipart/form-data" } ,
        body: { "lang":"fas" , "image":bytes},
        encoding: Encoding.getByName("utf-8")
    );

    return response.body;

  }

но я не знаю, как загрузить файл изображения, в приведенном выше коде я получаю исключение: Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
Как мне написать тело запроса?

Ответ 1

Ваш обходной путь должен работать; многие серверы принимают application/x-www-form-urlencoded в качестве альтернативы (хотя данные кодируются умеренно неэффективно).

Однако для этого можно использовать dart: http. Вместо использования http.post вы захотите использовать объект http.MultipartFile.

Из документации дротика:

var request = new http.MultipartRequest("POST", url);
request.fields['user'] = '[email protected]';
request.files.add(http.MultipartFile.fromPath(
    'package',
    'build/package.tar.gz',
    contentType: new MediaType('application', 'x-tar'),
));
request.send().then((response) {
  if (response.statusCode == 200) print("Uploaded!");
});

Ответ 2

Я бы рекомендовал вам пакет dio, dio - мощный Http-клиент для Dart/Flutter, который поддерживает перехватчики, FormData, отмену запросов, загрузку файлов, тайм-аут и т.д.

dio очень прост в использовании, в этом случае вы можете:

Отправка FormData:

FormData formData = new FormData.from({
   "name": "wendux",
   "file1": new UploadFileInfo(new File("./upload.jpg"), "upload1.jpg")
});
response = await dio.post("/info", data: formData)

Подробнее см. dio。.

Ответ 3

Это может быть достигнуто с помощью класса MultipartRequest (https://docs.flutter.io/flutter/package-http_http/MultipartRequest-class.html)

Измените тип носителя и URI по мере необходимости.

uploadFile() async {
    var postUri = Uri.parse("<APIUrl>");
    var request = new http.MultipartRequest("POST", postUri);
    request.fields['user'] = 'blah';
    request.files.add(new http.MultipartFile.fromBytes('file', await File.fromUri("<path/to/file").readAsBytes(), contentType: new MediaType('image', 'jpeg')))

    request.send().then((response) {
      if (response.statusCode == 200) print("Uploaded!");
    });
  }

Ответ 4

В классе MultipartFile есть статический метод, который будет называться fromPath, который возвращает Future. Вы можете добавить файл в тело запроса, используя метод request.files.add().

final postUri = Uri.parse(kAPIUrl);
http.MultipartRequest request = http.MultipartRequest('POST', postUri);

http.MultipartFile multipartFile =
await http.MultipartFile.fromPath('image_file', filePath); //returns a Future<MultipartFile>

request.files.add(multipartFile);

http.StreamedResponse response = await request.send();