Сunning fetch()
If you want to submit a form without form.submit() you need to know two things.
At first fetch() send pre-flight requests (OPTIONS). You can temporary turn off it by adding ‘Access-Control-Max-Age’. But this is not about that.
And second fetch() add ‘Content-Type’ automatically. If you want to set ‘application/json’, everything is OK. But as soon as you try to set ‘multipart/form-data’, you have problems.
The trick is that actual ‘content-type’ header which send to server contents boundary string for ‘multipart/form-data’ as well.

Just allow to fetch() make his work. Don’t add ‘content-type’ by yourself.