Due to the large file uploading of the project recently, I reviewed the relevant knowledge of file uploading recently, and especially sorted out some notes

Js image preview two ways

  • To manipulate a file (image), you first need HTML support, which supports the following tags for manipulating and selecting a file
<input type="file" />
Copy the code
<! The following image previews the HTML structure of the code
  <input type="file" onchange="handleFileChange1(this)" />
  
  <input type="file" onchange="handleFileChange2(this)" />
  
Copy the code
  • The first way :(using bloburl) the core API in js isURL.createObjectURL
   
    // 2 With url.createObjecturl, it turns the file object into a blob object, which is read directly by the IMG tag

    function handleFileChange2(instance) {
      const file = instance.files[0];
      imgUrl = globalThis.URL.createObjectURL(file);
      const img = new Image();
      img.alt = img.title = file.name;
      img.src = imgUrl;
      document.body.appendChild(img);
    }
Copy the code

  • The second way :(using dataurl) comparison consumes the core API in jsFileReader readAsDataURL
  // 1 converts the image to base64 via readAsDataURL
    function handleFileChange1(instance) {
      const file = instance.files[0];
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = (e) = > {
        const base64URL = e.target.result;
        const img = new Image();
        img.alt = img.title = file.name;
        img.src = base64URL;
        document.body.appendChild(img);
      };
    }
Copy the code

Js to achieve a single picture upload two ways

<! The following image previews the HTML structure of the code
    <input type="file" id="file1">

    <input type="file" id="file2">
  
Copy the code
  • Scheme 1: Based on form-data
      / / based on formData
      document.getElementById('file2').onchange = async function() {
        var files = this.files
        if (files.length <= 0) return
        var formData = new FormData()
        formData.append('file', files[0])
        formData.append('filename', files[0].name)
        var res = await axios.post('http://127.0.0.1:8888/single1', formData)
        if (res.data.code == 0) {
          var img = new Image()
          img.src = res.data.path
          document.body.appendChild(img)
        }
      }


Copy the code
  • Scheme 2: Convert the selected file to BASE64 and pass BASE64 to the server
      / / based on base64

        function getBase64(file) {
          return new Promise((resolve, reject) = > {
            var ready = new FileReader()
            ready.readAsDataURL(file)
            ready.onload = function(e) {
              resolve(e.target.result)
            }
          })
        }
      document.getElementById('file1').onchange = async function() {
        var files = this.files
        if (files.length <= 0) return
        // console.log(files)
        var base64 = await getBase64(files[0])
        var filename = files[0].name
        // console.log(filename, base64)
        var res = await axios.post('http://127.0.0.1:8888/single2', Qs.stringify({ chunk: encodeURIComponent(base64), filename }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded'}})if (res.data.code == 0) {
          var img = new Image()
          img.src = res.data.path
          document.body.appendChild(img)
        }
      }
Copy the code

Js to achieve multiple picture upload

    <section class="uploadBox clearfix">
        <div class="card button">
            <input type="file" id="uploadInp" accept="image/*" multiple>
        </div>

        <! -- <div class="card"> <img src="images/1.png" alt=""> <div class="progress"> <div class="line"></div> </div> <div class="mark"></div> </div> -->
    </section>
Copy the code
  (function () {
            // Request encapsulation
            function postRequest(url, data, config) {
                config = config || {};
                return axios.post(` http://127.0.0.1:8888${url}`, data, config).then(response= > {
                    return response.data;
                });
            }

            // File read
            function fileReader(file) {
                return new Promise(resolve= > {
                    let reader = new FileReader;
                    reader.readAsDataURL(file);
                    reader.onload = ev= > {
                        resolve(ev.target.result);
                    };
                });
            }

            // Delay function
            function delay(interval) {
                interval = interval || 500;
                return new Promise(resolve= > {
                    setTimeout(() = > {
                        resolve();
                    }, interval);
                });
            }

            let uploadBox = document.querySelector('.uploadBox'),
                button = uploadBox.querySelector('.button'),
                uploadInp = uploadBox.querySelector('#uploadInp');
            button.onclick = function () {
                uploadInp.click();
            };
            uploadInp.onchange = async function () {
                let self = this,
                    files = Array.from(self.files);
                if (files.length === 0) return;

                // Build the upload list
                let uploadList = [];
                files.forEach((file, index) = > {
                    uploadList[index] = {
                        file: file,
                        base64: null.card: null
                    };
                });

                // Base64&&create CARD dynamically
                let base64List = await Promise.all(files.map(file= > fileReader(file))),
                    frag = document.createDocumentFragment();
                base64List.forEach((base64, index) = > {
                    let card = document.createElement('div');
                    card.className = 'card';
                    card.innerHTML = `
                        <img src="${base64}" alt="">
                        <div class="progress">
                            <div class="line"></div>
                        </div>
                        <div class="mark"></div>
                    `;
                    frag.appendChild(card);
                    // Complete the upload list
                    uploadList[index].base64 = base64;
                    uploadList[index].card = card;
                });
                uploadBox.appendChild(frag);

                await delay();

                // Upload pictures in batches according to the upload list && monitor the progress
                uploadList.forEach(async item => {
                    let {
                        file,
                        base64,
                        card
                    } = item;

                    let data = {
                            chunk: encodeURIComponent(base64),
                            filename: file.name
                        },
                        config = {
                            headers: {
                                "Content-Type": "application/x-www-form-urlencoded"
                            },
                            // Upload progress detection
                            onUploadProgress(ev) {
                                // ev.loaded && ev.total
                                let ratio = ev.loaded / ev.total * 100 + The '%';
                                card.querySelector('.line').style.width = ratio; }};let response = await postRequest('/single2', Qs.stringify(data), config);
                    if (response.code === 0) {
                        // Upload succeeded
                        await delay();
                        let progress = card.querySelector('.progress'),
                            mark = card.querySelector('.mark');
                        card.removeChild(progress);
                        card.removeChild(mark);
                    }
                });
            };
        })();
Copy the code

The reference code of the file upload server is as follows

// Back-end code
/*-CREATE SERVER-*/
const express = require('express'),
    app = express(),
    bodyParser = require('body-parser'),
    fs = require('fs'),
    SparkMD5 = require('spark-md5'),
    PORT = 8888;
app.listen(PORT, () = > {
    console.log('THE WEB SERVICE IS CREATED SUCCESSFULLY AND IS LISTENING TO THE PORT:${PORT}`);
});
app.use((req, res, next) = > {
    res.header("Access-Control-Allow-Origin"."*");
    req.method === 'OPTIONS' ? res.send('CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS! ') : next();
});
app.use(bodyParser.urlencoded({
    extended: false.limit: '1024mb'
}));

/*-API-*/
const multiparty = require("multiparty"),
    uploadDir = `${__dirname}/upload`;

function handleMultiparty(req, res, temp) {
    return new Promise((resolve, reject) = > {
        // Multiparty configuration
        let options = {
            maxFieldsSize: 200 * 1024 * 1024}; ! temp ? options.uploadDir = uploadDir :null;
        let form = new multiparty.Form(options);
        / / multiparty parsing
        form.parse(req, function (err, fields, files) {
            if (err) {
                res.send({
                    code: 1.reason: err
                });
                reject(err);
                return;
            }
            resolve({
                fields,
                files
            });
        });
    });
}

// Upload DATA based on form-data
app.post('/single1'.async (req, res) => {
    let {
        files
    } = await handleMultiparty(req, res);
    let file = files.file[0];
    res.send({
        code: 0.originalFilename: file.originalFilename,
        path: file.path.replace(__dirname, ` http://127.0.0.1:${PORT}`)}); });/ / upload BASE64
app.post('/single2'.(req, res) = > {
    let {
        chunk,
        filename
    } = req.body;

    // Chunk processing: convert to buffer
    chunk = decodeURIComponent(chunk);
    chunk = chunk.replace(/^data:image\/\w+; base64,/."");
    chunk = Buffer.from(chunk, 'base64');

    // Store files to the server
    let spark = new SparkMD5.ArrayBuffer(),
        suffix = /\.([0-9a-zA-Z]+)$/.exec(filename)[1],
        path;
    spark.append(chunk);
    path = `${uploadDir}/${spark.end()}.${suffix}`;
    fs.writeFileSync(path, chunk);
    res.send({
        code: 0.originalFilename: filename,
        path: path.replace(__dirname, ` http://127.0.0.1:${PORT}`)}); }); app.use(express.static('/'));
app.use((_, res) = > {
    res.status(404);
    res.send('NOT FOUND! ');
});

Copy the code