Ionaru / easy-markdown-editor

EasyMDE: A simple, beautiful, and embeddable JavaScript Markdown editor. Delightful editing for beginners and experts alike. Features built-in autosaving and spell checking.
https://stackblitz.com/edit/easymde
MIT License
2.31k stars 308 forks source link

Node.js EasyMDE upload image #566

Closed larrybg closed 8 months ago

larrybg commented 9 months ago

I'm trying to use the local image upload functionality of the EasyMDE. I couldn't find any working example for Node.js. Here is my code:

Client side:

const easyMDE = new EasyMDE({
   element: document.getElementById('my-text-area'),
     autofocus: true,
     shortcuts: {
       drawTable: "Cmd-Alt-T"
     },
     hideIcons: ['image'],
     showIcons: ["code", "table", "upload-image"],
     uploadImage: true,
     imageUploadEndpoint: "imageUpload",
   });

Server side:

router.post("/imageUpload", async (req, res) => {
  console.log('receiving image...');
});

I'm receiving POST request, I insert a breakpoint on the console.log row but where do I find the actual image data to save to the disk in the reg object? Am I missing some steps?

Ionaru commented 8 months ago

The image should be in the FormData of the request.

The image upload code is here: https://github.com/Ionaru/easy-markdown-editor/blob/35587a94771756e095b2d1147539e2aedfd887d4/src/js/easymde.js#L2419

larrybg commented 8 months ago

can you please provide an example of how to upload an image? looks like easyMDE is already creating the FormData and there is nothing on my side I should do:

    var formData = new FormData();
    formData.append('image', file);

So I don't understand what am I doing wrong.

Ionaru commented 8 months ago

Explaining how to handle form/image data on the server side goes beyond the scope of what I believe should be handled in this repo. There's simply too many different implementations of the server-side possible.

It does look like you are using Node.js/Express so I suggest you look for related tutorials like this: https://codex.so/handling-any-post-data-in-express

larrybg commented 8 months ago

I'm not asking how to handle data on the server, I'm pointing out that the server doesn't receive any data, the request body data is empty in my case. My question is: in my configuration on the client side is that enough for your library to send the local image over to the server or my configuration is wrong or missing something:

const easyMDE = new EasyMDE({
   element: document.getElementById('my-text-area'),
     autofocus: true,
     shortcuts: {
       drawTable: "Cmd-Alt-T"
     },
     hideIcons: ['image'],
     showIcons: ["code", "table", "upload-image"],
     uploadImage: true,
     imageUploadEndpoint: "imageUpload",
   });

The imageUploadEndpoint: "imageUpload" is pointing to the server POST request where I can catch the incoming event, but as I've already stated the req.body is empty. Your documentation has a list of options and functions but unfortunately no explanation on how to put it together or examples. I was under the assumption that if I instruct your lib on where to send the POST request is sufficient ("imageUpload"), and I have received the request on the server side but there was no data, that is what confused me. Now do I have to write any additional code to process the file on the client side and send it to the server...? But your code already sends the POST request... and it is empty. Do I have to use another configuration - for example to remove the imageUploadEndpoint and replace it with imageUploadFunction?

Ionaru commented 8 months ago

Setting uploadImage: true and imageUploadEndpoint are enough to make the image upload work on the client.

req.body is empty, this is correct because the image is sent as form-data or multipart/form-data which ExpressJS does not parse by default.

From the tutorial I linked:

Express by default has no ability to parse this type of encoding.

Please look at those tutorials on how to process multipart/form-data file uploads on your server.

larrybg commented 8 months ago

Thank you! That is exactly the information I was missing. Everything is working as expected now.