I’m trying to upload files to an image hosting service that only accepts multipart/form-data content type. The problem is that I’m working in a restricted environment where the FormData constructor isn’t available.
Here’s what I would normally do if FormData was supported:
const uploadData = new FormData();
uploadData.append('image', fileUrl);
uploadData.append('preset_key', IMAGE_SERVICE_PRESET);
uploadData.append('service_name', IMAGE_SERVICE_NAME);
console.log(`Processing upload (ref: ${reference}) to image service`, SERVICE_ENDPOINT, uploadData);
const result = await fetch(SERVICE_ENDPOINT, {
method: 'POST',
body: uploadData,
});
I’ve attempted several workarounds but the API is very strict about the content format and won’t accept anything other than proper multipart form data. What alternatives exist for creating multipart requests when FormData is unavailable?
I’ve hit this same issue with legacy systems. You’ll have to build the multipart boundary and request body manually. Make a unique boundary string like ----formdata-${Date.now()}, then piece together the body by wrapping each field with the boundary and proper Content-Disposition headers. Don’t forget CRLF line endings between sections. Files need Content-Type headers too. Set your request’s Content-Type to multipart/form-data; boundary=your-boundary-string. More work than FormData, but it’s solid once you nail the formatting. Watch out for binary data handling if you’re uploading actual files instead of URLs - that’s where it gets tricky.
Had this exact problem last year with a custom upload service. The manual approach works, but here’s another option - create a hidden form in the DOM and submit it programmatically. Make a form with enctype="multipart/form-data", add hidden inputs for your data, then use XMLHttpRequest to capture and send it. This gets around the FormData limitation while still generating proper multipart encoding. Downside is you’re messing with the DOM, which might not work depending on your environment. For pure JavaScript, building the multipart body manually is your best bet. Just handle the boundary markers correctly and test thoroughly with your API endpoint.
Hit this nightmare a few times with embedded systems and weird runtime environments.
One trick that saved me: use a library like form-data if you can install packages. It handles boundary generation and encoding without needing browser FormData.
Going fully manual? Here’s what other answers missed - handle the file content right. Since you’re passing a fileUrl, fetch it first to get the binary data:
const fileResponse = await fetch(fileUrl);
const fileBuffer = await fileResponse.arrayBuffer();
When building your multipart body, convert that buffer properly. The boundary stuff’s easy once you get the pattern, but file encoding trips people up.
Also check if your restricted environment supports XMLHttpRequest with manual headers. Sometimes that works when fetch with FormData doesn’t.
Debugging tip - log the raw request body and compare it character by character with a working FormData request. That’s how I caught my CRLF issues.