axios-fetch-adapter
axios-fetch-adapter copied to clipboard
Incompatible with Service Workers and `FormData`
I recently came across an issue that is somewhat related to #16 where I was trying to upload a file to an AWS S3 bucket with a Presigned POST URL from inside a Manifest V3 Chrome Extension which requires the use of Service Workers.
axios.defaults.adapter = fetchAdapter;
const formData = new FormData();
Object.entries(fields).forEach(([key, value]) => {
formData.append(key, value);
});
formData.append('file', file);
await axios.post(s3Url, formData);
Unfortunately this was erroring due to the Content-Type
header being set to application/www-x-form-urlencoded
instead of multipart/form-data
and the WebKit boundary injected by the browser.
Looking into the code it seems the issue is caused by the use of isStandardBrowserEnv()
inside the check which should automatically remove the Content-Type
header, allowing the browser to fill in the correct one. This helper method is expecting window
and document
to be defined which is not possible in a Service Worker environment.
if (method !== 'GET' && method !== 'HEAD') {
options.body = config.data;
// In these cases the browser will automatically set the correct Content-Type,
// but only if that header hasn't been set yet. So that's why we're deleting it.
if (isFormData(options.body) && isStandardBrowserEnv()) {
headers.delete('Content-Type');
}
}
@vespaiach Removing the isStandardBrowserEnv()
from the if statement solves my problem and allows the file upload to succeed, but I am unsure if it will have any knock on effect to other use cases of this package?
faced with the same issue
It's way better to check if it's a spec compliant FormData
You could use options?.body?.[Symbol.toStringTag] === 'FormData'
to check if it should or shouldn't delete the header.
instead of using if (isFormData(options.body) && isStandardBrowserEnv())