Flutter:http post上传图片

Mne*_*oee 20 image-uploading httprequest dart flutter

我使用Web服务进行图像处理,它在Postman中运行良好:

邮差截图

现在我想用Dart扑灭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;

  }
Run Code Online (Sandbox Code Playgroud)

但我不知道如何上传图像文件,在上面的代码中我得到异常:Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
我应该如何编写请求体?

wen*_*ndu 20

我想向你推荐dio包,dio是Dart/Flutter的强大Http客户端,它支持Interceptor,FormData,Request Cancellation,File Downloading,Timeout等.

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)
Run Code Online (Sandbox Code Playgroud)

更多细节请参考dio.

  • 请在此处写下解决方案,而不是包含将来可能会损坏的链接。谢谢! (8认同)
  • @dipgirl UploadFileInfo 已弃用,现在有 MultiPartFromFile 类可以执行此操作。这是一个示例 https://github.com/flutterchina/dio#sending-formdata (3认同)
  • @wendu 我可以知道 UploadFileInfo() 函数来自哪里吗? (2认同)

rmt*_*zie 18

你的解决方法应该有效; 许多服务器将接受application/x-www-form-urlencoded作为替代方案(尽管数据编码效率适中).

但是,可以使用dart:http来执行此操作.而不是使用http.post,你会想要使用一个http.MultipartFile对象.

dart文档:

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!");
});
Run Code Online (Sandbox Code Playgroud)

  • 根据[此 github 问题],文档是错误的(https://github.com/dart-lang/http/issues/140) (2认同)

Qui*_*ner 16

我找到了一个没有使用任何外部插件的工作示例,这只使用

import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:convert';
Run Code Online (Sandbox Code Playgroud)

代码

var stream =
        new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
    // get file length
    var length = await imageFile.length(); //imageFile is your image file
    Map<String, String> headers = {
      "Accept": "application/json",
      "Authorization": "Bearer " + token
    }; // ignore this headers if there is no authentication

    // string to uri
    var uri = Uri.parse(Constants.BASE_URL + "api endpoint here");

    // create multipart request
    var request = new http.MultipartRequest("POST", uri);

  // multipart that takes file
    var multipartFileSign = new http.MultipartFile('profile_pic', stream, length,
        filename: basename(imageFile.path));

    // add file to multipart
    request.files.add(multipartFileSign);

    //add headers
    request.headers.addAll(headers);

    //adding params
    request.fields['loginId'] = '12';
    request.fields['firstName'] = 'abc';
   // request.fields['lastName'] = 'efg';

    // send
    var response = await request.send();

    print(response.statusCode);

    // listen for response
    response.stream.transform(utf8.decoder).listen((value) {
      print(value);

    });
Run Code Online (Sandbox Code Playgroud)


Cha*_*ena 11

2021年更新方式:

使用 flutter httpmime

import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'dart:io';


  Future<dynamic> multipartImageUpload(String baseUrl, String api, File image) async {
    var uri = Uri.parse(baseUrl + api);
    final mimeTypeData =
        lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');

    // Intilize the multipart request
    final imageUploadRequest = http.MultipartRequest('PUT', uri);

    // Attach the file in the request
    final file = await http.MultipartFile.fromPath('image', image.path,
        contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
    imageUploadRequest.files.add(file);

    // add headers if needed
    //imageUploadRequest.headers.addAll(<some-headers>);

    try {
      final streamedResponse = await imageUploadRequest.send();
      final response = await http.Response.fromStream(streamedResponse);
      return response;
    } catch (e) {
      print(e);
      return null;
    }
  }
Run Code Online (Sandbox Code Playgroud)


小智 9

如何在flutter/dart中使用restAPI上传图片文件。

这对我有用。

var postUri = Uri.parse("apiUrl");

http.MultipartRequest request = new http.MultipartRequest("POST", postUri);

http.MultipartFile multipartFile = await http.MultipartFile.fromPath(
    'file', filePath); 

request.files.add(multipartFile);

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


print(response.statusCode);
Run Code Online (Sandbox Code Playgroud)


Sup*_*iya 8

使用MultipartRequest类。 如何在flutter/dart中使用restAPI上传图片文件

  void uploadImage1(File _image) async {

    // open a byteStream
    var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
    // get file length
    var length = await _image.length();

    // string to uri
    var uri = Uri.parse("enter here upload URL");

    // create multipart request
    var request = new http.MultipartRequest("POST", uri);

    // if you need more parameters to parse, add those like this. i added "user_id". here this "user_id" is a key of the API request
    request.fields["user_id"] = "text";

    // multipart that takes file.. here this "image_file" is a key of the API request
    var multipartFile = new http.MultipartFile('image_file', stream, length, filename: basename(_image.path));

    // add file to multipart
    request.files.add(multipartFile);

    // send request to upload image
    await request.send().then((response) async {
      // listen for response
      response.stream.transform(utf8.decoder).listen((value) {
        print(value);
      });

    }).catchError((e) {
      print(e);
    });
  }
Run Code Online (Sandbox Code Playgroud)

命名空间:

import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
Run Code Online (Sandbox Code Playgroud)


Sil*_*der 8

要添加标头并将 http multipart 与https://pub.dev/packages/multi_image_picker插件一起使用,

这是代码。

var request =  http.MultipartRequest(
        'POST', Uri.parse(myurl)

      );
      //Header....
      request.headers['Authorization'] ='bearer $authorizationToken';
      
       request.fields['PropertyName'] = propertyName;
    request.fields['Country'] = country.toString();
    request.fields['Description'] = des;
    request.fields['State'] = state.toString();
       request.files.add(http.MultipartFile.fromBytes(
      'ImagePaths',
      learnImage,
      filename: 'some-file-name.jpg',
  contentType: MediaType("image", "jpg"),
    )
        );
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
  print(res.body);
Run Code Online (Sandbox Code Playgroud)

使用 HTTP 和https://pub.dev/packages/image_picker 插件

这是代码

var request =  http.MultipartRequest(
        'POST', Uri.parse(myurl)

      );
      request.headers['Authorization'] ='bearer $authorizationToken';
       request.fields['PropertyName'] = propertyName;
    request.fields['Country'] = country.toString();
    request.fields['Description'] = des;
    request.fields['State'] = state.toString();
       request.files.add(await http.MultipartFile.fromPath(
      'ImagePaths',
      file.path
    )
        );
var response = await request.send();
    print(response.stream);
    print(response.statusCode);
    final res = await http.Response.fromStream(response);
      print(res.body);
Run Code Online (Sandbox Code Playgroud)


小智 7

这可以使用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!");
    });
  }
Run Code Online (Sandbox Code Playgroud)

  • 像魅力一样工作。:) tnq这么多:)只需添加:-请为contentType添加“ import'package:http_parser / http_parser.dart';” (4认同)
  • 您重要的“MediaType”来自哪里? (4认同)
  • 对我有用,只需将 ```File.fromUri("&lt;path/to/File"&gt;) ``` 更改为 ```File.fromUri(Uri.parse("&lt;path/to/file&gt;"))` `` (3认同)
  • @BagusAjiSantoso request.send 不返回``Future&lt;Response&gt;```,它返回````Future&lt;StreamedResponse&gt;```。看到这个问题/sf/ask/3886458061/ (2认同)

Erk*_*bay 6

使用表单数据将图像上传到服务器

要将图像上传到服务器,您需要一个dio库。

特征:

  1. 授权(添加令牌)
  2. 添加额外的字段,如:用户名等
  3. 添加要上传的图片

代码示例:

import 'package:dio/dio.dart' as dio;
import 'dart:convert';

    try {
      ///[1] CREATING INSTANCE
      var dioRequest = dio.Dio();
      dioRequest.options.baseUrl = '<YOUR-URL>';

      //[2] ADDING TOKEN
      dioRequest.options.headers = {
        'Authorization': '<IF-YOU-NEED-ADD-TOKEN-HERE>',
        'Content-Type': 'application/x-www-form-urlencoded'
      };

      //[3] ADDING EXTRA INFO
      var formData =
          new dio.FormData.fromMap({'<SOME-EXTRA-FIELD>': 'username-forexample'});

      //[4] ADD IMAGE TO UPLOAD
      var file = await dio.MultipartFile.fromFile(image.path,
            filename: basename(image.path),
            contentType: MediaType("image", basename(image.path)));

      formData.files.add(MapEntry('photo', file));

      //[5] SEND TO SERVER
      var response = await dioRequest.post(
        url,
        data: formData,
      );
      final result = json.decode(response.toString())['result'];
    } catch (err) {
      print('ERROR  $err');
    }
Run Code Online (Sandbox Code Playgroud)