Flutter: http post upload an image

2019-04-05 18:46发布

问题:

I use a web service for image processing , it works well in Postman:

Now I want to make http request in flutter with Dart:

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;

  }

but I don't know how to upload the image file, in above code I get exception: Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
How should I write the body of request?

回答1:

Your workaround should work; many servers will accept application/x-www-form-urlencoded as an alternative (although data is encoded moderately inefficiently).

However, it is possible to use dart:http to do this. Instead of using http.post, you'll want to use a http.MultipartFile object.

From the dart documentation:

var request = new http.MultipartRequest("POST", url);
request.fields['user'] = 'someone@somewhere.com';
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:

I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.

dio is very easy to use, in this case you can:

Sending FormData:

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

More details please refer to dio。



回答3:

This can be achieved using the MultipartRequest class (https://docs.flutter.io/flutter/package-http_http/MultipartRequest-class.html)

Change the media type and uri as needed.

uploadFile() async {
    var postUri = Uri.parse("<pathToFile>");
    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!");
    });
  }