As far as web servers are concerned, we’ll focus on the input: File and FS modules in egg, discuss how to implement file uploads, and give examples of how image files can be processed on the server.

Before we begin, we recommend that you learn about the file type of the input control and the FS module in Node.js.

The client uploads files

Usually we use the input control’s file type to upload files, which can be used as a combination of form forms and input controls alone.

Input control

input:file

    <label for="">Photo upload:<input id="file" type="file" value="Select picture" multiple></label>
    <br>
    <button onclick="upload()">upload</button>
Copy the code

An Ajax request

Here I started with XHR for Ajax requests, but there was a problem with the requesting server not receiving the file, so I used AXIos instead. Use the modified code directly here, if you already know axios to write your own code.

The sent file uses the FormData data type and requires multipart/form-data as the content-type parameter.

    let file = document.querySelector('#file').files[0]
    let formData = new FormData()
    formData.append("uploadFile", file, file.name)
    const config = {
        headers: {
            "Content-Type": "multipart/form-data; boundary=" + new Date().getTime()
        }
    };
    axios
        .post("/file", formData, config)
        .then(function (response) {
            console.log(response);
        })
        .catch(function (error) {
            console.log(error);
        });
    }
Copy the code

At this point our client can send a full POST request and send the file file to the server as formData.

The server receives the file

Accept the file

Whether you send a file or multiple files, the server receives an array of files.

console.log(ctx.request.files[0])// The first file in a single file or multiple files.
Copy the code
  • Ctx.request. files[0] Print contents:
{
  field: 'uploadFile'.filename: 'Double Scarty.jpg'.encoding: '7bit'.mime: 'image/jpeg'.fieldname: 'uploadFile'.transferEncoding: '7bit'.mimeType: 'image/jpeg'.filepath: 'C:\ Users\ Li 小 you \\AppData\\Local\ Temp\\ Egg-multipart-tmp \\work2\\2021\ 09\ 23\ 21\ e0bbd897-F1B2-4475-b616-ad4DD7f73ebf. jpg' 
}
Copy the code

Field, filename, MIME, etc. We already know this before we generate the formData data type to send the request. The key is the Filepath property, because of this property we cache the file to the address indicated by Filepath when the HTTP request data is successfully transferred. This means that we can copy the file to the specified location and also manipulate the file (image to base64, etc.).

Using the image cache address Filepath, we can retrieve images after they have been uploaded.

Base encoding stores images

Next we will discuss image file processing. For base64 encoding, we need to use the FS module.

    async index() {
        // Declare the address variable
        const { ctx } = this;
        const file = ctx.request.files[0];
        // Image processing
        let imgbase64 = await fs.readFileSync(file.filepath,'base64')
        await fs.unlinkSync(file.filepath)
        ctx.body = {
            msg: 'ok'.img: imgbase64
        }
    }
Copy the code

Here, in order to obtain the base64 encoding information of uploaded pictures, we use the encoding function in the fs module built in Node for processing:

  • ReadFileSync is a synchronization function that takes two parameters (image cache path, encoding mode) and returns the encoding result

  • ReadFile is an asynchronous function that takes three arguments (the third argument is a callback function). Note that readFileSync not only executes in a different order but also takes different arguments. The argument to the callback function is the encoding result.

We don’t use readFile here because we need to respond to the encoded result to the client. If we just store it to the database, we can use readFileSync asynchronously to avoid blocking (synchronous blocking is not obvious).

The server stores images locally

Using the fs module’s copyFileSync method, we can copy the image file requested by the client, that is, save it to a customized location as local permanent storage.

    async index() {
        // Multiple path variables
        const { ctx } = this;
        const file =  ctx.request.files[0];
        const toFileName = '/public/upload/'+Date.now()+file.filename;
        const to = path.dirname(__dirname)+toFileName;
        // Copy the image to the local directory
        await fs.copyFileSync(file.filepath,to)
        await fs.unlinkSync(file.filepath)
        const newUrl = "http://juejinjin.com:80"+toFileName;
        console.log(this.ctx.request.files[0])
        ctx.body = {
            msg: 'ok'.url: newUrl
        }
    }
Copy the code

With the unlinkSync function, we turn off Filepath, which eliminates the image cache, because we have copied a copy of the image. Then through the path combination can access the public routing address response to the client, the client can directly request to get the picture through this URL, that is, the network address of the picture.

The whole article, in fact, around the formData data type and FS module to implement, through these two knowledge points we can be invariable should change, solve the problem of file transfer between the client and the server. As for how to deal with the transferred files is the specific situation of the specific discussion can not be separated from fs module.

This is the end of our egg-based learning. I will consider whether or not to update the depth according to my learning status.