matthew-andrews / isomorphic-fetch

Isomorphic WHATWG Fetch API, for Node & Browserify
MIT License
6.96k stars 290 forks source link

Post file/blob using multipart formdata ? #100

Open leplatrem opened 7 years ago

leplatrem commented 7 years ago

In the browser, if I do something like:

    var headers = {Authorization: "Basic " + btoa("user:pass")};
    // Build form data
    var formData = new FormData();
    // File obtained via File API
    formData.append('attachment', file, file.name);
    // Some data as JSON
    formData.append('data', JSON.stringify({foo: "bar"}));
    // Post using GlobalFetch API
    fetch(url, {method: "POST", body: formData, headers: headers})
      .then(...)

The request issued in the browser will have Content-Type:"multipart/form-data; boundary=---------------------------<random-number> and the body will be like:

-----------------------------<random-number>
Content-Disposition: form-data; name="attachment"; filename="velo.jpg"
Content-Type: image/jpeg

ÿØÿà ....

-----------------------------<random-number>
Content-Disposition: form-data; name="data"

{"foo":"bar"}
-----------------------------<random-number>--

I would also work (from the browser) using blobs:

const blob = new Blob([new Uint8Array(array)], {type: "image/jpeg"});
formData.append('attachment', blob, "velo.jpg");

For our integration tests we're using isomorphic-fetch@2.2.1 and jsdom@9.4.1 and we can't get obtain the same behavior (content-type and body seem to remain empty). I could not find any existing issue that was specific to multiparts (#30 is about FormData).

Is that something reasonably feasible ? Can we help ?

Thanks a lot!

justinjzs commented 7 years ago
function upload() {
  const formData = new FormData(document.getElementById('myForm'));
  const headers = {
    'Accept': 'application/json, */*',
    'Content-Type': 'multipart/form-data'
  }
  const init = {
    headers,
    method: 'POST',
    body: formData
  };
  fetch('/upload', init).then(res => console.log(res));
}

I try to POST files by that func, but the 'boundary' is not in request payload. how should i do? below is the request payload:

------WebKitFormBoundary2gPDSneqBnpU2L4v Content-Disposition: form-data; name="files"; filename="fox.jpg" Content-Type: image/jpeg

------WebKitFormBoundary2gPDSneqBnpU2L4v Content-Disposition: form-data; name="path"

/ ------WebKitFormBoundary2gPDSneqBnpU2L4v--

gusdaud-zz commented 7 years ago

Hey @justinjzs take 'Content-Type' out of the headers. The browser should add it automatically (including the boundary).

AdarshKonchady commented 6 years ago

@gusdaud @justinjzs @leplatrem Was this issue resolved? boundary is not being passed for me in the request header automatically even after explicitly setting 'Content-Type': 'multipart/form-data' header.

jsellers180 commented 6 years ago

Does anyone have a working example of this?

jayaramkasi commented 5 years ago

@gusdaud's solution worked for me.

This should be closed