HTML web page file transfer

#1

If you are asking a question, please follow this template:

  1. My goal is: [describe your goal]
    ti use a phone or tablet connecting to a esp32 web server (AP mode) and transfer a file (~2K) to the file system on the esp32

  2. My actions are: [describe your actions - code, commands, etc]
    HTML server working, file selection working. Unable to actually get the file transfer going.
    I’m not sure exactly how to chunk the file and get it into the server. What commands are needed in the HTML code and where do I process the web page response to do the file write and the command used?

  3. The result I see is: [show the result - log, etc]
    no file transfer happened.

  4. My expectation & question is: [describe your expectation and your question]
    file transfered to the esp32

#2

You can use RPC to call FS.Put
Example of RPC call from javascript

#3

I already tried using this, but all it gives me is an empty file. So I figured it might be a chunking problem.
data.filename=file.name;
data.len=file.size;
axios.post(’/rpc/FS.Put’, data)

I also already use this for the config – works fine.
axios.post(’/rpc/Config.Set’, obj).then(function(res) {
return axios.post(’/rpc/Config.Save’, {reboot: false});

#4

The arguments are filename: %Q, offset: %ld, data: %V, append: %B where data is base64 encoded.

#5

so I can’t send a plain txt file? It has to be encoded?

#6

"data": "base64 text"

#7

Ahhhh… I always got the impression that “based64 text” was a parameter not the actual data
So If I have a file[0] text file how do I make it base64 encoded and pass that to the Put?

#8

Google for “javascript base64”

#9

Need a little more help for a noobie:
I added this function:
image

Then I used mos to get the file:

I expected to get the plain text result of the file that was uploaded.
I assume I must still be under a false impression or I an doing something wrong.

#10

https://codepen.io/AshV/pen/pjodjV

#11

I tried to use this example previously and was unsuccessful. I’m not a JavaScript expert by any means. In my screenshot above it looks like I just need to get rid of the dataAtext/… before the base64 stuff. It seems so close.

I appreciate your trying to help me.

#12

FOUNDIT! - needed a btoa() call

function getBase64(file) {
var reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function () {
axios.post(’/rpc/FS.Put’, {“filename”: file.name, “data”: btoa(reader.result)})
.then(res => /* do something with res*/ console.log(res))
.catch(e => console.log(‘upload failed’))
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}

#13

Now I’m getting “upload failed” logged to the console when I try to upload a 25k file. Shouldn’t FS.Put automatically chunk the file to the file system? Do I have to wait for a successful finish? Or is the try/catch good enough? ~2k files seem to be ok.

#14

The error is due to the default size of MGOS_RECV_MBUF_LIMIT which is 3072

The best solution would be to send chunks of the base64 encoded data and use the append flag.

#15

I’m struggling here. JavaScript noobie.
I can get the entire file in reader.result, but I can’t seem to find the right syntax to slice it out to chunk.
Also, should I be using readAsBinaryString, readAsArrayBuffer, or readAsText?
I’m kind of surprised that there isn’t a simple example in Mongoose OS somewhere to help get a leg up on this (or better yet a library call). I suppose I should also be using Promise too?

#16

Mongoose OS provides the basic functions.

It is the developer’s responsibilty to use/combine them in order to achieve what he/she wants.

#17

Well it’s probably very poor code and it seems to be flaky as all get out, but in case anybody has need of it or can improve it this seems to at least work some of the time:
(Making chunkSize bigger made it even more flaky)

function postFileToServer(file) {
	var chunkSize = 1000;
	var fileSize = (file.size - 1);
	
	var putit = function(e){
	  axios.post('/rpc/FS.Put', {"filename": file.name, "append": false, "data": btoa(e.target.result)})
		.then(console.log('false'))
		.catch(e => console.log('upload failed.'))
	  console.log(e.target.result);
	};

	var putit_ext = function(e){
	  axios.post('/rpc/FS.Put', {"filename": file.name, "append": true, "data": btoa(e.target.result)})
		.then(console.log('true'))
		.catch(e => console.log('upload failed'))
	  console.log(e.target.result);
	};

	for(var i =0; i < fileSize; i += chunkSize) {
		(function( fil, start ) {
			var reader = new FileReader();
			var blob = fil.slice(start, chunkSize + start);
			if (i>=chunkSize)
				reader.onload = putit_ext;
			else
				reader.onload = putit;
			reader.readAsText(blob);
 console.log(i);
		})(file, i);
	}
}