New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
postForm's form-data serialization breaks for Blob in Node.js #6352
Comments
Axios supports Node v12 and above, so we can't just go the easy way and use the latest built-ins but have to support different formData implementations, as Axios is designed to be as flexible as possible. const {data} = await axios.postForm('http://httpbin.org/post', {
x: 1,
stream: fs.createReadStream('1.txt')
}); or set another(native) FormData implementation as default. const {data} = await axios.postForm('http://httpbin.org/post', {
x: 1,
blob: await fs.openAsBlob('2.txt')
}, {
env: {
FormData // native FormData constructor
}
}); |
Describe the bug
When I try to have
postForm
automatically serialize aBlob
in Node.js, it fails with the error message"Blob is not supported. Use a Buffer instead."
I dug into it a bit, and it seems the culprit is a combination of things.To Reproduce
POST /api/upload
(or whatever endpoint you'd like)/tmp/image.jpg
(or wherever you'd like)Code snippet
Expected behavior
postForm
serializes the object containing theBlob
asFormData
and uploads it successfullyAxios Version
1.6.8
Adapter Version
No response
Browser
Node.js
Browser Version
v21.7.3
Node.js Version
v21.7.3
OS
macOS 14.4.1
Additional Library Versions
Additional context/Screenshots
On lib/helpers/toFormData.js:92,
formData
gets instantiated asPlatformFormData
, which comes from theform-data
package. This probably shouldn't happen, since Node.js has its own built-inFormData
. I'd suggest swapping the order of that||
statement to have any environment's built-inFormData
take precedence.There's a long-standing bug in
form-data
, form-data/form-data#396, whereinFormData[Symbol.toStringTag]
isundefined
.FormData[Symbol.iterator]
is alsoundefined
, but that's not covered in the issue. However, it is relevant here. The functionisSpecCompliantForm
(lib/utils.js:632) uses these to check whether whatever's getting passed in (thing
) is indeed an instance ofFormData
. I'd suggest doing that a different way, such as usinginstanceof
.What does all this have to do with
Blob
? Well, for some reason that's beyond me, intoFormData
,isSpecCompliantForm
is tied touseBlob
(lib/helpers/toFormData.js:110), the boolean that determines whether or notBlob
is supported. In factBlob
is supported, by virtue of the fact that_Blob
is defined in the previous line. I'd suggest decoupling these expressions, since bundling togetherFormData
validation andBlob
validation is too complex for one boolean, especially when the name of that boolean only references one of them. It unnecessarily breaksBlob
support based on a bug in a third-party implementation ofFormData
—which, as you'll recall from earlier, we probably shouldn't even prefer to use in the first place.Another question that comes to mind is: why do we even need to validate
FormData
at all here? Since we're already preferring a specific version of a third-party implementation ofFormData
, I think we can safely assume that what we have on our hands is actually a spec-compliantFormData
(except, of course, for the finer details ofSymbol.toStringTag
whereform-data
differs fromFormData
). The only reason I can think of to validateFormData
is if (as we should) we preferred to use the environment's built-inFormData
, which might differ between environments. And doing that would actually fix this bug altogether.The text was updated successfully, but these errors were encountered: