如何使用Flutter将图像上传到服务器API

时间:2019-11-20 04:13:35

标签: flutter dart

我是Flutter开发的新手。我的问题是我尝试上传图片,但请求不断失败。

这一段代码是我将其与服务器API连接的地方,该服务器API将从Flutter接收图像文件。字符串附件,该字符串附件是从位于另一页的createIncident函数传递的图像路径组成的。

Future<IncidentCreateResponse> createIncident( String requesterName, String requesterEmail, 
                                              String requesterMobile, String attachment, String title,
                                              String tags, String body, String teamId,
                                              String address )  async {
    IncidentCreateResponse incidentCreateResponse;
    var url = GlobalConfig.API_BASE_HANDESK + GlobalConfig.API_INCIDENT_CREATE_TICKETS;
    var token = Auth().loginSession.accessToken;
    var postBody = new Map<String, dynamic>();
    postBody["requester_name"] = requesterName;
    postBody["requester_email"] = requesterEmail;
    postBody["requester_mobile_no"] = requesterMobile;
    postBody["attachment"] = attachment;
    postBody["title"] = title;
    postBody["tags"] = tags;
    postBody["body"] = body;
    postBody["teamId"] = teamId;
    postBody["address"] = address;

    // Await the http get response, then decode the json-formatted responce.
    var response = await http.post(
        url,
        body: postBody,
        headers: {
          'X-APP-ID': GlobalConfig.APP_ID,
          "Accept": "application/json; charset=UTF-8",
          // "Content-Type": "application/x-www-form-urlencoded",
          HttpHeaders.authorizationHeader: 'Bearer $token',
          'token': GlobalConfig.API_INCIDENT_REPORT_TOKEN  
        }
      );
    if ((response.statusCode == 200) || (response.statusCode == 201)) {
      print(response.body);
      var data = json.decode(response.body);

      incidentCreateResponse = IncidentCreateResponse.fromJson(data['data']);
    } else {
      print("createIncident failed with status: ${response.statusCode}.");

      incidentCreateResponse = null;
    }

    return incidentCreateResponse;
  }

这是我从图库中选择的图像中获取图像路径的代码段

Future getImageFromGallery(BuildContext context) async {
    var picture = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState((){
      _imageFile = picture;
      attachment = basename(_imageFile.path);
    });
    Navigator.of(context).pop();
  }

这是我将附件字符串传递给HTTP响应的代码

this.incidentService.createIncident(
     Auth().loginSession.name, 
     Auth().loginSession.email, 
     Auth().loginSession.mobile_no, 
     this.attachment,
     this._titleController.text, 
     this._tags, 
     this._contentController.text, 
     this._teamId,
     this._addressController.text
).then((IncidentCreateResponse res) {
     if (res != null) {
        print('Ticket Id: ' + res.id);
        // Navigator.pop(context);
        this._successSubmittionDialog(context);
     } else {
        this._errorSubmittionDialog(context);
     }
}

3 个答案:

答案 0 :(得分:1)

您可以使用多部分或base64编码上传图像。

要使用多部分上传图像,请访问Official documentation

要使用base64编码上传图像,您可以检出Tutorial Here

我建议使用分段图像上传,因为当您的图像或文件较大时,它甚至是可靠的。

答案 1 :(得分:0)

希望这可以为您提供帮助,

创建一个功能,可以在选择或单击类似图像后上传图像,

Future<ResponseModel> uploadPhoto(
  String _token,
  File _image,
  String _path,
) async {
  Dio dio = new Dio();
  FormData _formdata = new FormData();
  _formdata.add("photo", new UploadFileInfo(_image, _path));
  final response = await dio.post(
    baseUrl + '/image/upload',
    data: _formdata,
    options: Options(
      method: 'POST',
      headers: {
        authTokenHeader: _token,
      },
      responseType: ResponseType.json,
    ),
  );
  if (response.statusCode == 200 || response.statusCode == 500) {
    return ResponseModel.fromJson(json.decode(response.toString()));
  } else {
    throw Exception('Failed to upload!');
  }
}

然后您可以使用uploadImage

uploadImage(_token, _image,_image.uri.toFilePath()).then((ResponseModel response) {
   //do something with the response
});

我已使用Dio进行任务,您可以找到有关dio here的更多详细信息

将此添加到您程序包的pubspec.yaml文件中:

dependencies:
  dio: ^3.0.5

然后将其导入您的Dart代码中,您可以使用:

import 'package:dio/dio.dart';

答案 2 :(得分:0)

要使用多部分API上传图像,请使用以下代码,即

将此库dio添加到项目中的pubspec.yaml文件中

dio: ^3.0.5

并将其导入您的班级

import 'package:dio/dio.dart';

在您的课程中声明此变量,例如State<CustomClass>

static var uri = "BASE_URL_HERE";
  static BaseOptions options = BaseOptions(
      baseUrl: uri,
      responseType: ResponseType.plain,
      connectTimeout: 30000,
      receiveTimeout: 30000,
      validateStatus: (code) {
        if (code >= 200) {
          return true;
        }
      });
  static Dio dio = Dio(options);

然后使用此方法上传文件

Future<dynamic> _uploadFile() async {
    try {
      Options options = Options(
          //contentType: ContentType.parse('application/json'), // only for json type api
          );

      var directory = await getExternalStorageDirectory(); // directory path
      final path = await directory.path; // path of the directory
      Response response = await dio.post('/update_profile',
          data: FormData.from({
            "param_key": "value",
            "param2_key": "value",
            "param3_key": "value",
            "profile_pic_param_key": UploadFileInfo(File("$path/pic.jpg"), "pic.jpg"),

          }),
          options: options);
      setState(() {
        isLoading = false;
      });
      if (response.statusCode == 200 || response.statusCode == 201) {
        var responseJson = json.decode(response.data);
        return responseJson;
      } else if (response.statusCode == 401) {
        print(' response code 401');
        throw Exception("Incorrect Email/Password");
      } else
        throw Exception('Authentication Error');
    } on DioError catch (exception) {
      if (exception == null ||
          exception.toString().contains('SocketException')) {
        throw Exception("Network Error");
      } else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
          exception.type == DioErrorType.CONNECT_TIMEOUT) {
        throw Exception(
            "Could'nt connect, please ensure you have a stable network.");
      } else {
        return null;
      }
    }
  }