react-native: [Android] FormData fails to send data in multipart/form-data

As per https://github.com/facebook/react-native/pull/1357#issuecomment-171378913 @philikon implemented uploading files (images) via the NetworkingModule.java.

The following works on iOS (image and description are sent to server and received correctly) on iOS. On Android, the request is made but both image and description are missing from the request.

let formData = new FormData();
formData.append('image', {uri: image.uri, type: 'image/jpg', name: 'image.jpg'});
formData.append('description', String(data.description));

let options = {};
options.headers['Content-Type'] = 'multipart/form-data; boundary=6ff46e0b6b5148d984f148b6542e5a5d';
options.body = formData;
return fetch(uri, options).then((response) => {
   .... 
});

Where image.uri is either an android or ios file:

  • android: file:///storage/emulated/0/Pictures/eb645893-4c00-44a3-a9b4-a2116e955f7c.jpg
  • ios: /Users/ashleydw/Library/Developer/CoreSimulator/Devices/23EE88D0-6E91-43AD-A3B6-06F87698C5A8/data/Containers/Data/Application/A73E68D3-7424-4301-9934-AD0F8251C1EB/tmp/7803DA8A-0E40-4FCB-A593-884805878172.jpg

I’ve tried both with and without it file://. Without it, the NetworkingModule.java reaches “Could not retrieve file for uri /storage/emulated/0/Pictures/8505b7c8-389e-4a0a-8d0a-7669891031f9.jpg” on line https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java#L166.

With it, the requests send but the data is missing.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 30
  • Comments: 21 (6 by maintainers)

Most upvoted comments

Hey ashleydw, thanks for reporting this issue!

React Native, as you’ve probably heard, is getting really popular and truth is we’re getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If you don’t know how to do something or something is not working as you expect but not sure it’s a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • If this is a feature request or a bug that you would like to be fixed, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • We welcome clear issues and PRs that are ready for in-depth discussion. Please provide screenshots where appropriate and always mention the version of React Native you’re using. Thank you for your contributions!
let xhr = new XMLHttpRequest();
xhr.open('POST', this.baseUrl + '/mobileapi/user/picture');
let formdata = new FormData();
// image from CameraRoll.getPhotos(
formdata.append('image', {...image, name: 'image.jpg', type: 'image/jpeg'});
xhr.send(formdata);

This works on Android

Removing the Content-Type header resolved this.

I’m using RN 0.40+ In my case, multiples photos, I solved problem with below code.

let data = new FormData()

    _.each(params.photos, (photo) => {
      data.append('photos[]', {uri: photo.uri, type: photo.type, name: photo.fileName});
    })

    data.append('title', params.title)
    data.append('description', params.description)
    data.append('price', params.price)
    data.append('city', params.city)
    data.append('state', params.state)
    data.append('status', params.status)
    data.append('category_id', params.category_id)
    data.append('user_id', params.user_id)

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'multipart/form-data',
        'Authorization': `Bearer ${params.token}`
      },
      body: data
    })

I think there is a problem if you use ‘image/jpg’ instead of the correct one: ‘image/jpeg’ Not sure if this can cause a problem or just having the incorrect type is the reason.

Check: Media Types

xhr.setRequestHeader('content-type', 'multipart/form-data');

You should not have to specify this.

formdata.append('image', {...image, name: 'image.jpg', type: 'multipart/form-data'});

That content-type is simply wrong. You want image/jpeg or something like that.

Using RN 27 I had to both remove my boundary: section from the multipart header and add the file:// prefix if Platform.OS === 'android' (Still using FormData()) Thanks for your pointers.

@ashleydw first off, you should not be setting your own content type header. The point of using FormData is that FormData takes care of that, in particular generating a random boundary etc.

As for your problem, have you tried using regular XMLHttpRequest? Just to rule out fetch as a source of the bug.

Also, just to rule out weirdness with your server, have you tried using another server to verify that your data is indeed not being sent, e.g. https://www.posttestserver.com? The UIExplorer app does that. The iOS version actually uploads an image: https://github.com/facebook/react-native/blob/master/Examples/UIExplorer/XHRExample.ios.js#L217. The Android version doesn’t (yet), but it could easily be modified to do so (perhaps you can submit a PR?).