This is the 11th day of my participation in the More text Challenge. For more details, see more text Challenge

preface

This article is designed to show you how to upload images using JS. It describes two methods, one using Ajax and the other using Axios.

In fact, the following code is also suitable for uploading files, just modify the upload restrictions a little. This article is also worth a look if you are uploading other types of files instead of pictures.

The following assumes that JQ is referenced.

To prepare

First, put a hidden input to read the image file and an upload button.

<! -- For previewing images, do not write -->
<img class="img" src="">

<! -- used to read images -->
<input class="input-img" type="file" accept="image/*" style="display: none;">

<! -- Used to trigger events -->
<button class="upload-btn">Select Picture Upload</button>
Copy the code

The hidden Input click event is triggered when the upload button is fired.

$('.upload-btn').click(function () {$('.input-img').click()
})
Copy the code

The ajax way

When the hidden input is triggered, the computer or mobile phone will pop up a new window to prompt the user to select the picture. After the user has selected the picture, the change event of the input will be triggered. At this time, we should listen to the change event and write our own business logic in it.

Note: The change event must check whether the file in the input has a value, because the change event will also be triggered if the file in the input is cleared.

$('.input-img').on('change'.function () {
    var file = $('.input-img').get(0).files[0]
    if(! file || file.length ==0) {
      return
    }
    var fileName = file.name;
    var fileType = fileName.substr(fileName.lastIndexOf(".")).toUpperCase();
    if(fileType ! =".GIF"&& fileType ! =".PNG"&& fileType ! =".JPG"&& fileType ! =".JPEG") {
      alert('Please select the picture file! ') / / hint
      return
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if(! isLt2M) { alert('Upload image size cannot exceed 2MB! ') / / hint
      $('.input-img').get(0).value = ' '
      return
    }
    
    // Sometimes we need to preview the image before we upload it, so we can convert the image into Base64 and display it
    $('.img').attr('src', fileToBase64(file))
    
    var formdata = new FormData()
    formdata.append("file", file)
    
    $.ajax({
        url: 'Back-end address'.method: 'post'.data: formdata,
        processData:false.// Data serialization is not required because the data being transferred is a FormData object
        contentType:false.// You don't need a content-type field with headers, because passing the FormData object already defaults to mutipart/form-data
        xhr: function () {
            var xhr = new XMLHttpRequest()
            xhr.upload.addEventListener('progress'.function(e) {
                if (e.lengthComputable) {
                    var progress = Math.round(e.loaded * 100 / e.total) + The '%'
                    console.log('Upload progress:', progress)
                } else {
                    console.log('Unable to calculate upload progress')
                }
            })
            xhr.upload.addEventListener('load'.function(e) {
                console.log('Upload successful')
            })
            xhr.upload.addEventListener('error'.function(e) {
                console.log('Upload failed')
            })
            xhr.upload.addEventListener('abort'.function(e) {
                console.log('User cancelled upload/browser disconnected')})return xhr
        }
    }).done(function (data) {
        console.log('The message returned by the backend:' + data)
    }).fail(function (err) {
        console.log(err)
        alert('Server exception')})})/** * File flow to base64 *@param {*} file 
  */
function fileToBase64(file) {
    var URL = window.URL || window.webkitURL;
    return URL.createObjectURL(file);
}  
Copy the code

Axios way

Just replace the Ajax part of the above code with axios

axios({
      url: "Back-end address".method: "post".headers: {
        "Content-Type": "multipart/form-data"
      },
      data: formdata,
      withCredentials: false.onUploadProgress: function (e) {
          var progress = Math.round(e.loaded / e.total * 100) + The '%'
          console.log('Upload progress:', progress)
      }
}).then(res= > {
      console.log('Data returned by the backend:' + res)
      console.log('Upload successful')
}).catch(err= > {
      console.log('Upload failed')})Copy the code

Upload multiple images at once

If you want to upload multiple images at the same time, you need to add multiple to the hidden input to allow multiple images to be read at the same time.

<input class="input-img" type="file" accept="image/*" style="display: none;" multiple>
Copy the code

The change event in js needs to be modified slightly. Instead of just reading the first file, it now reads the files array.

$('.input-img').on('change'.function () {
      // Read the array of files
      var files = $('.input-img').get(0).files
      if(! files || files.length ==0) {
        return
      }
      // Check each file
      for (var file of files) {
            var fileName = file.name;
            var fileType = fileName.substr(fileName.lastIndexOf(".")).toUpperCase();
            if(fileType ! =".GIF"&& fileType ! =".PNG"&& fileType ! =".JPG"&& fileType ! =".JPEG") {
              alert('Please select the picture file! ') / / hint
              return
            }
            const isLt2M = file.size / 1024 / 1024 < 2;
            if(! IsLt2M) {alert(upload image size cannot exceed 2MB!)/ / hint
              $('.input-img').get(0).value = ' '
              return}}... })Copy the code

For the following interface request, you need to see whether the back-end interface supports the upload of multiple images at the same time. If not, then the interface is called once for each image uploaded.