Skip to content

How to upload a file from the browser to Node RED

Julian Knight edited this page Jun 26, 2022 · 2 revisions

If you want to use uibuilder/Node-RED to upload a file from a client device to the server, this is the process to use.

1. Create an inbound endpoint in Node-RED

Currently (as at uibuilder v5), there is no direct method to upload to Node-RED from the browser via uibuilder.

Instead add a http-in and http-out connected pair of nodes to a flow. Make the http-in node use the POST method. Also change the settings for that node to allow file uploads.

The output of the http-in node must go both to an http-out (which returns a success or fail http code) and to a set of node(s) to handle the incoming form data.

See the example flow at the end of the page.

2. Create a form in your front-end UI code

<form action="/upload" method="POST" enctype="multipart/form-data">
    <input type="file" name="myFile" />
    <input type="submit" />
</form>

Note that if you are using a 204 response code from Node-RED to stay on the same page, you will likely wish to add some JavaScript to clear out the file name after upload.

Security

The transfer is only secure if you make it so. You need to at least implement TLS encryption (e.g. use HTTPS not HTTP). Then you should also validate the upload data before blindly assuming that it is safe. For example, check the file mimetype matches the filename extension, block unsafe file types (or better still have an allow list of types), limit the filename length and characters, limit the buffer size.

You should also only be allowing updates from known and authenticated users.

You might also want to have checks of available storage before committing the file and some other process to clear down old files or limit space utilisation.

Example flow

[{"id":"6081b5d0ba078956","type":"http in","z":"bfec3af46a41235d","name":"","url":"/upload","method":"post","upload":true,"swaggerDoc":"","x":280,"y":380,"wires":[["54b563baa08e10b5","add8ee6a9e62361e"]]},{"id":"54b563baa08e10b5","type":"http response","z":"bfec3af46a41235d","name":"","statusCode":"204","headers":{},"x":800,"y":380,"wires":[]},{"id":"c86833183e63bf4c","type":"debug","z":"bfec3af46a41235d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":460,"wires":[]},{"id":"c6fed61b5941f570","type":"file","z":"bfec3af46a41235d","name":"","filename":"","appendNewline":false,"createDir":false,"overwriteFile":"true","encoding":"none","x":720,"y":460,"wires":[["c86833183e63bf4c"]]},{"id":"add8ee6a9e62361e","type":"change","z":"bfec3af46a41235d","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"req.files[0].buffer","tot":"msg"},{"t":"set","p":"filename","pt":"msg","to":"req.files[0].originalname","tot":"msg"},{"t":"set","p":"encoding","pt":"msg","to":"req.files[0].encoding","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":460,"wires":[["c6fed61b5941f570"]]}]
Clone this wiki locally