'Upload image as file to server flutter

I want upload file to server with form-data. The server receives two files.

Here is the code web team used for upload documents from react-js.

import React from 'react';
import axios from 'axios';
import { Flex, Text } from '@chakra-ui/react';
import { GenerateChecksum } from 'Lib/utils';
import { Card } from '../Styles';


function Index() {

  const handleChange = async (e) => {
    const { files } = e.target;

    const meta = {
      Name: 'name',
      Type: 'SIGN',
      Value: '',
      Formats: '',
      Hash: '',
      Size: '',
    };

    const maxAllowedSize = 5 * 1024 * 1024;

    if (files.length > 0) {
      if (files[0].size > maxAllowedSize) {
        console.log('File is too big!');
      }

      const formData = new FormData();



      // First File
      formData.append('document', files[0]);

      // Set Meta file.
      meta.Size = files[0].size;
      meta.Formats = files[0].type;
      meta.Hash = await GenerateChecksum(files[0]); // gererates hash value

      const blob = new Blob([JSON.stringify(meta)], {
        type: 'application/json',
      });



      // Second File 
      const metaData = new File([blob], 'meta.json', { type: 'application/json' });

      formData.append('meta', metaData);

      axios
        .post('<---upload-url--->', formData, {
          headers: { 'Content-Type': 'multipart/form-data' },
        })
        .then((result) => result.data)
        .then(async ({ data }) => {
          console.log('File Uploaded Successfully!');
        })
        .catch((err) => {
          console.log('Upload Failed!', err.message);
        });
    }
  };

  return (
    <Card mb={4}>
      <Flex>
        <Flex flex={1} direction="column">
          <input
            type="file"
            onChange={handleChange}
            style={{ display: 'none' }}
            accept="image/png, image/jpg, image/jpeg"
          />
          <Text color="#979797" fontWeight="600" fontSize="19px" mb={4}>
            Add image
          </Text>
        </Flex>
      </Flex>
    </Card>
  );
}

export default Index;

Both document and meta are files that we need to upload server.

  1. First file - Directly taken from disk. So they added to formdata.
  2. Second file - They used blob and converted into File.

Now I want upload file from flutter app. Here is the code I tried to upload, but getting error like 404, and Gateway timeout 504 error. I tried with both http and dio packages to upload.

import 'dart:convert';
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:dio/dio.dart' as dio;
import 'dart:async';

Future<void> upload() async {
  /// For generate hash value
  var hash = await compute(generateImageHash, File(pickedFile!.path!));

  var meta = {
    "Name": "name",
    "Type": "SIGN",
    "Value": "",
    "Formats": pickedFile!.path!.split(".").last,
    "Hash": hash,
    "Size": pickedFile!.size.toString(),
  };

  Directory dir = await getTemporaryDirectory();
  File _file = File("${dir.path}/meta.json");
  File file = await _file.writeAsString(json.encode(meta));

  var url = "<---upload-url---->";

  dio.FormData formData = dio.FormData();
  dio.Dio().options.headers["Content-Type"] = "multipart/form-data";

  formData.files.add(
    MapEntry(
      "document",
      await dio.MultipartFile.fromFile(
        pickedFile!.path!,
        filename: pickedFile!.path!.split("/").last,
        contentType: MediaType("image", pickedFile!.path!.split(".").last),
      ),
    ),
  );

  formData.files.add(
    MapEntry(
      "meta",
      await dio.MultipartFile.fromFile(
        file.path,
        contentType: MediaType("application", "json"),
        filename: file.path.split("/").last,
      ),
    ),
  );

  var resp = await dio.Dio().post(
    url,
    data: formData,
    options: dio.Options(
      method: 'POST',
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    ),
  );

  print(resp.statusCode);

  // var request = http.MultipartRequest("POST", Uri.parse(url));

  // request.files.add(
  //   http.MultipartFile(
  //     'document',
  //     pickedFile!.readStream!,
  //     File(pickedFile!.path!).lengthSync(),
  //     filename: pickedFile!.path!.split("/").last,
  //   ),
  // );

  // request.files.add(
  //   http.MultipartFile(
  //     'meta',
  //     PlatformFile(name: file.path.split("/").last, size: ),
  //     File(file.path).lengthSync(),
  //     filename: file.path.split("/").last,
  //   ),
  // );

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

  // print(res.statusCode);
}

How can I correctly upload a file to the server?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source