【问题标题】:How to upload image to server API with Flutter [duplicate]如何使用 Flutter 将图像上传到服务器 API [重复]
【发布时间】:2020-03-15 17:05:15
【问题描述】:

我是 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;
  }

这是代码 sn-p,我从图库中的选定图像中获取图像路径

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);
     }
}

【问题讨论】:

  • 在这里查看我的答案,这可能会对您有所帮助stackoverflow.com/a/58800596/5734205
  • 非常感谢。我将测试您提供的解决方案。我认为这不是重复,因为他的要求和我的要求有点不同。
  • 好的,你可以通过我的方案上传单张和多张图片。

标签: flutter dart


【解决方案1】:

您可以使用 multipart 或 base64 编码上传图片。

使用分段上传图片访问Official documentation

如需使用 base64 编码上传图片,您可以查看Tutorial Here

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

【讨论】:

    【解决方案2】:

    希望对你有帮助,

    创建一个函数以在选择或单击图像后上传您的图像,

    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';
    

    【讨论】:

      【解决方案3】:

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

      在你的项目中的pubspec.yaml文件中添加这个库dio

      dio: ^3.0.5
      

      并将其导入您的班级

      import 'package:dio/dio.dart';
      

      在你的类中声明这个变量,比如State&lt;CustomClass&gt;

      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;
            }
          }
        }
      

      【讨论】:

      • “UploadFileInfo”出现错误。我错过了什么吗?
      猜你喜欢
      • 2021-01-18
      • 2017-12-04
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 2022-07-25
      • 2020-01-01
      • 2021-02-27
      • 2018-08-24
      相关资源
      最近更新 更多