抖动dio上传文件[pdf / docs]

时间:2020-03-09 02:33:39

标签: flutter dart dio

我正在尝试使用我的flutter应用程序中的dio包上传文件。我正在通过formdata发送文件。这是我的实现:

Future<FormData> formData1() async {
    return FormData.fromMap({
      "title": "from app2",
      "description": "app upload test",
      "files": [
        for (var i = 0; i < pathNames.length; i++)
          await MultipartFile.fromFile(pathNames[i],
              filename: fileNames[i])
      ]
    });
  }

这是我发送文件的方式。

_sendToServer() async {
    Dio dio = Dio(
      BaseOptions(
        contentType: 'multipart/form-data',
        headers: {
          "Authorization": "$token",
        },
      ),
    );
    dio.interceptors.add(
        LogInterceptor(requestBody: true, request: true, responseBody: true));
    FormData formData = await formData1();
    try {
      var response = await dio.post("http://url/api/upload",
          data: formData, onSendProgress: (int send, int total) {
        print((send / total) * 100);
      });
      print(response);
    } on DioError catch (e) {
      if (e.response != null) {
        print(e.response.data);
        print(e.response.headers);
        print(e.response.request);
      } else {
        print(e.request.headers);
        print(e.message);
      }
    }
  }

formdata中的其他字段发送到服务器,但不发送到multipartfile。当我尝试从邮递员表单数据中执行相同操作时,它会正确上传。我在这里做错什么了吗?

5 个答案:

答案 0 :(得分:0)

通过以下休息更改formdata很好

   import 'package:path/path.dart' as pathManager;
    import 'package:mime/mime.dart' as mimeManager;

FormData formdata = FormData();

 formdata.add(
          "files",
          [UploadFileInfo(img, pathManager.basename(img.path),
          contentType:
              ContentType.parse(mimeManager.lookupMimeType(img.path)))]);

答案 1 :(得分:0)

// here attachmentFile is File instance, which is set by File Picker

Map<String, dynamic> _documentFormData = {};

if (attachmentFile != null) {
        _documentFormData['document_file'] = MultipartFile.fromFileSync(attachmentFile.path);
}
FormData formData = FormData.fromMap(_documentFormData);

try {
      var response = await dio.post("http://url/api/upload",
          data: formData, onSendProgress: (int send, int total) {
        print((send / total) * 100);
      });
      print(response);
    } on DioError catch (e) {
      if (e.response != null) {
        print(e.response.data);
        print(e.response.headers);
        print(e.response.request);
      } else {
        print(e.request.headers);
        print(e.message);
      }
    }

答案 2 :(得分:0)

如果您要上传文件,则可以在调用API函数之前转换多部分数组,因为即使您在form data dio中等待,响应也不会等待formdata对象,或者您可以使用MultipartFile.fromFileSync()摆脱等待。

让我使用我的示例以简单的方式向您展示。尝试了解。

分段转换

List multipartArray = [];
for (var i = 0; i < pathNames.length; i++){
   multipartArray.add(MultipartFile.fromFileSync(pathNames[i], filename: 
   basename(pathNames[i])));
}

Api端

static Future<Response> createPostApi(multipartArray) async {
    var uri = Uri.parse('http://your_base_url/post');
    return await Dio()
        .post('$uri',
            data: FormData.fromMap({
              "title": "from app2",
              "description": "app upload test",
              "files": multipartArray
            }))
        .catchError((e) {
      print(e.response.data);
      print(e.response.headers);
      print(e.response.request);
    });
  }

答案 3 :(得分:0)

在这里,您可以使用 MultipartRequest 类而不使用任何库来使用 restAPI 上传任何类型的文件。

void uploadFile(File file) async {

    // 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 "idDocumentOne_1" is a key of the API request
    MultipartFile multipartFile = await http.MultipartFile.fromPath(
          'idDocumentOne_1',
          file.path
    );

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

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

    }).catchError((e) {
      print(e);
    });
  }

我使用文件选择器来选择文件。这是选择文件的代码。

Future getPdfAndUpload(int position) async {

    File file = await FilePicker.getFile(
      type: FileType.custom,
      allowedExtensions: ['pdf','docx'],
    );

    if(file != null) {

      setState(() {

          file1 = file; //file1 is a global variable which i created
     
      });

    }
  }

这里是 file_picker 颤振库。

答案 4 :(得分:0)

这是我使用 file_picker flutter 库和 MediaType('application', 'pdf') 来确保传递给 API 的内容确实是 .pdf 文件的代码。

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';

static Future<dynamic> uploadfile(int userid, File file, String token) async {
  var fileName = file.path.split('/').last;
  print(fileName);
  var formData = FormData.fromMap({
    'title': 'Upload Dokumen',
    'uploaded_file': await MultipartFile.fromFile(file.path,
        filename: fileName, contentType: MediaType('application', 'pdf')),
    "type": "application/pdf"
  });

  var response = await Dio().post('${urlapi}request/',
      options: Options(
          contentType: 'multipart/form-data',
          headers: {HttpHeaders.authorizationHeader: 'Token $token'}),
      data: formData);
  print(response);
  return response;
}

文件选择器:

FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
  File file = File(result.files.single.path ??'file.pdf');
  BlocProvider.of<UploadCubit>(context)
                                   .uploadFile(statelogin.user.id, file,
                                          statelogin.user.token);
}