I'm currently trying to setup a multipart/form-data
request in a flutter app which uploads a picture taken via the device's camera, using flutters image picker package.
To take the picture, I simply use:
final takenPicture = await ImagePicker().pickImage(
source: ImageSource.camera
);
fileForUpload = File(takenPicture.path);
I then upload the file according to the docs using:
var uri = Uri.https('example.com', 'create');
var request = http.MultipartRequest('POST', uri)
..fields['user'] = 'nweiz@google.com'
..files.add(await http.MultipartFile.fromPath(
'pictures[]', fileForUpload.path,
filename: 'sample.jpg',
contentType: MediaType('image', 'jpg')));
var response = await request.send();
if (response.statusCode == 200) print('Uploaded!');
This now works. The problem I have is that, when you omit the filename
and the contentType
argument in the MultipartFile.fromPath
constructor, the upload occasionally fails with the error message:
the file exists, but the PHP is_readable() function fails when passed the path to the file.
Pretty much like in this answer, it only worked once I added a random filename and content type to the request, as shown above; then the error stopped showing up.
I know that the Multipart class applies the application/octet-stream
by default as the content-type of the image; is that maybe the reason? When I var_dump()
the $_FILES
variable on the server-side for the times where the above-mentioned upload error occurs, I can see that tmp_name
is empty, which is probably the reason why the server-side cannot find the upload. When I add the above-mentioned filename
and contentType
parameters, the tmp_name
property of all uploads is always present and the upload seemingly never fails.
Besides the fact that I would really like to understand why this happens, I would also like to know how you should actually set the filename + media type for an image that has been taken via the image picker package. To my understanding, that depends on the device if the image you've selected is png
, jpg
, heic
, etc. Simply extract the mime type via the suffix from the filename, as the upload is then validated on the server-side anyways? Just because the docs do not really explain about the MediaType
part.