form-data / form-data

A module to create readable `"multipart/form-data"` streams. Can be used to submit forms and file uploads to other web applications.
https://www.npmjs.com/form-data
MIT License
2.27k stars 291 forks source link

[error] can not append "object" as "Blob" #529

Open sylvanfrost opened 2 years ago

sylvanfrost commented 2 years ago

environment

node - 15.7.0 (first version has blob as experimental) form-data - ^4.0.0

problem

  1. I tried to append form data as Blob.
  2. I need to append as real object not object as string.
  3. If has other way to append form data as real object I will go that way but I don't know how.

why

My api develop by Hapi framework and validate by Joi. When api get a request Hapi will use Joi validate payload first (not my code), I need to validate some key in payload as my expected object joi exmaple

Joi.object({
  "a": Joi.object({
    "a": Joi.string(),
    "b": Joi.number().required()
  });
});

remark

JavaScript in html file can append blob

code

const { Blob } = require("buffer");
const formData = require("form-data");

const objectHere = {
  "a": 1,
  "b": 2
}
const objectAsBlob = new Blob([JSON.stringify(objectHere, null, 0)], { type: "application/json" });

formdata.append("data", objectAsBlob); // error at this line

error

> node ./index.js

Debugger attached.
Waiting for the debugger to disconnect...
C:\Users\username\poc\node_modules\delayed-stream\lib\delayed_stream.js:33
  source.on('error', function() {});
         ^

TypeError: source.on is not a function
    at Function.DelayedStream.create (C:\Users\username\poc\node_modules\delayed-stream\lib\delayed_stream.js:33:10)
    at FormData.CombinedStream.append (C:\Users\username\poc\node_modules\combined-stream\lib\combined_stream.js:45:37)
    at FormData.append (C:\Users\username\poc\node_modules\form-data\lib\form_data.js:75:3)
    at C:\Users\username\poc\index.js:48:24
    at Array.forEach (<anonymous>)
    at GenerateServerInjectionOptions (C:\Users\username\poc\index.js:44:23)
    at Object.<anonymous> (C:\Users\username\poc\index.js:67:14)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:973:32)
npm ERR! code 1
npm ERR! path C:\Users\username\poc
npm ERR! command failed
npm ERR! command C:\Windows\system32\cmd.exe /d /s /c node ./index.js

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\username\AppData\Local\npm-cache\_logs\2022-02-22T04_16_37_431Z-debug.log
Waiting for the debugger to disconnect...

in html (work)

<script>
  const xhr = new XMLHttpRequest();
  const formData = new FormData();

  const objectHere = {
    "a": 1,
    "b": 2
  }
  const objectAsBlob = new Blob([JSON.stringify(objectHere, null, 0)], { type: "application/json" });

  formData.append("data", objectAsBlob);

  xhr.open("POST", "http://localhost:8080/poc");
  xhr.send(formData); // can sent and receive 
</script>
anhvule commented 2 years ago

FormData doesn't support Blob. Try this instead. It works!

formData.append('name', JSON.stringify(request), { contentType: "application/json" });
headers: {
  "Authorization": "Bearer " + accessToken,
  ...formData.getHeaders()
}
sylvanfrost commented 2 years ago

FormData doesn't support Blob. Try this instead. It works!

formData.append('name', JSON.stringify(request), { contentType: "application/json" });
headers: {
  "Authorization": "Bearer " + accessToken,
  ...formData.getHeaders()
}

thank you for answer, but I already try this way before like this...

const generateRequest = () => {
  // somecode

  returnOptions.headers = { ...returnOptions.headers, ...FD.getHeaders(), ...options.headers };
  returnOptions.payload = FD.getBuffer();

  return returnOptions;
}

after this function, I send formData to my api but Joi cant validation aa field like object (joi throw aa field -> "This field must be an object")

// my Joi Validation
const JoiValidation = Joi.Object({
  aa: joi.Array().items(Joi.Object({
    oa: Joi.string(),
    ob: Joi.string()
  }))
});
Worik42 commented 2 years ago

same the problem. I have a blob pdf file. I need to insert it into the form data. NestJS, axios.

ProdigyView commented 2 years ago

Same problem, and according to the docs, FormData does support Blob: https://developer.mozilla.org/en-US/docs/Web/API/FormData/append

ubudragon commented 1 year ago

it's a nightmare with bytes \ blobs and form-data it simply doesn't work at all

niemal commented 1 year ago

Yeah, I don't get it how it so broken. I tried grabbing the Blob's stream() and getReader() after that but still nothing.

dodancs commented 1 year ago

@anhvule

formData.append('name', JSON.stringify(request), { contentType: "application/json" });
headers: {
  "Authorization": "Bearer " + accessToken,
  ...formData.getHeaders()
}

Thank you, this resolved my issue and it worked as expected!

facadesss commented 1 year ago

the same problem, i solved it with formdata-node package

samabel98 commented 7 months ago

FormData doesn't support Blob. Try this instead. It works!

formData.append('name', JSON.stringify(request), { contentType: "application/json" });
headers: {
  "Authorization": "Bearer " + accessToken,
  ...formData.getHeaders()
}

but if i need it as blob to send it to multer , how can i do it ?