File Upload API

Blocks provides an HTTP API for uploading files, for example images. Uploaded files are temporarily stored in a subdirectory of the temp directory inside your Blocks root directory. This directory is not externally accessible for reading data. Thus, uploaded files must then be moved or further processed by a script. As an example, this application note describes how to upload photos subsequently shown on a Display Spot.

:!: IMPORTANT: Unless explicitly protected by an upload API key and value in the configuration file, uploads are not restricted in any other way. If an upload is specified, all upload requests must add an apiKey query parameter to the URL, with the expected value, or the upload will be rejected.

Upload file using multipart/form-data

URL: /rest/upload/multipart

The form must contain the following data:

  • target: The name of the subdirectory in the PIXILAB-Blocks-root/temp directory in which to store the file.
  • file: The file to upload.
  • fileName (optional): An optional file name. A leading * (asterisk) can be used to create a unique temporary file name.

The server returns the path to the file under the temp directory or, in case of errors, an error message along with a status code indiating an error.

Here's an HTML form for uploading a file to the temp/test directory. The HTML document containing the form must be served by the Blocks server:

<form action="/rest/upload/multipart" method="post" enctype="multipart/form-data">
    <input type="text" name="target" value="test" hidden>
    <input type="file" name="file">
    <input type="submit">
</form>

Upload a text snippet as urlencoded data

URL: /rest/upload/urlencoded/{target}/{filename}

  • {target} names a subdirectory inside the temp directory in your Blocks root, where to store the file.
  • {filename} is the name of the file. A leading * (asterisk) can be used to autogenerate a unique, temporary file name. A ".jpg" file extension will be automatically appended to the file name if no file extension is specified.

The server returns the path inside the temp directory where the file was stored or, in case of an error, an error message along with status code indiating an error.

Here's is a JavaScript example showing how to upload a short text snippet (specified by the body) to a file with a unique file name using this method. The promise returned by the fetch call will eventually provide the path to the file if the upload was successful.

fetch("/rest/upload/urlencoded/test/*.txt", {
    method: "post",
    headers: {
        "Content-Type": "application/x-www-form-urlencoded"
    },
    body: "Hello world"
});

Upload an image as urlencoded data

Here's is an example showing how to upload a PNG image with a unique file name as urlencoded data. Once this is done, the script logs the server-side name of the file, which you would then normally use to call some custom API endpoint on the server with this information for further processing of the uploaded image.

<canvas id="canvas" width="640" height="480"></canvas>
<button id="upload">Upload canvas image</button>

<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// Draw something on the canvas.
ctx.fillStyle = "red";
ctx.arc(320, 240, 100, 0, 2 * Math.PI);
ctx.fill();

document.getElementById("upload").addEventListener("click", function() {
    
    // Convert canvas content to Blob (containing PNG data).
    canvas.toBlob(async function(blob) {
        
        // Upload image as PNG.
        let res = await fetch("/rest/upload/urlencoded/test/*.png", {
            method: "post",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded"
            },
            body: blob
        });

        // Retrieve file name from response and log it in the console.
        let fileName = await res.text();
        console.log(fileName);
    });
});
</script>