silkimen / cordova-plugin-advanced-http

Cordova / Phonegap plugin for communicating with HTTP servers. Allows for SSL pinning!
MIT License
391 stars 313 forks source link

Can't set name to file when sending FormData #499

Closed jsoldi closed 11 months ago

jsoldi commented 1 year ago

Hi, I'm trying to use this to send a file in a FormData, which needs to have a name because the API I'm using fails if the file doesn't have a specific extension on the name. So I was naively passing FormData like this:

const fd = new FormData();
const file = new File([audioBlob], 'some_name.mp3'); // audioBlob is passed to this function
fd.append('file', file);
// Pass fd to `sendRequest`

The problem is that I also need cordova-plugin-file, which globally redefines File as something completely different that cannot be read by sendRequest.

So I tried a little hack, since I see that sendRequest will internally use the name in the Blob or File object:

const fd = new FormData();
(audioBlob as any).name = 'openai.mp3';
fd.append('file', audioBlob);

But that also won't work because FormData.append will internally convert the Blob into a File (and actual native File this time) and ignore the name. So I tried a second hack:

const fd = new FormData();
fd.append('file', audioBlob);
[...fd.entries()][0][1].name = 'openai.mp3';

But native File object won't let me change the name, it's still 'blob'. So now I'm stuck and I wonder if anyone knows a way to give a name to my file when sending it in a FromData.

silkimen commented 11 months ago

I'm not sure if this will help, but did you try to use the ponyfilled version of FormData which is shipped with this plugin? See https://github.com/silkimen/cordova-plugin-advanced-http/wiki/Web-APIs-required-for-Multipart-requests for details.

e.g. using

const fd = new cordova.plugin.http.ponyfills.FormData();
const file = new File([audioBlob], 'some_name.mp3'); // audioBlob is passed to this function
fd.append('file', file);
// Pass fd to `sendRequest`
jsoldi commented 11 months ago

I don't know about that plugin, but I ended up saving the native File type in my index.html file like this:

<script>
    // Save native File before cordova-plugin-file overwrites it
    window.NativeFile = window.File;
</script>

Then I can create a native file that I can pass to my form data like:

new (window as any).NativeFile([audioBlob], 'some_name.mp3', { type: 'audio/mpeg' });
silkimen commented 11 months ago

Okay, thanks for the feedback! I am closing this as your problem seems to be solved. Feel free to create a new ticket if you face another problem. 👍