Skip to content
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .upload-container {
      width: 500px;
      height: 100%;
      border: 1px solid #ebebeb;
      margin: 0 auto;
      margin-top: 50px;
      box-shadow: 3px 3px rgba(0, 0, 0, .3);
      padding: 0 30px;
      padding-bottom: 50px;
    }

    .upload-container .upload-btn {
      margin-top: 10px;
    }

    .upload-container .upload-btn .disabled {
      background-color: #dddddd !important;
    }

    .upload-container .upload-btn .select{
      height: 32px;
      background-color: #409eff;
      font-size: 12px;
      border: none;
      border-radius: 3px;
      color: #fff;
    }
    
    .upload-container .upload-tip {
      font-size: 12px;
      color: #606266;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <section class="upload-container">
    <input name="upload-inp" type="file" style="display: none;">
    <div class="upload-btn">
      <button class="select">点击自动上传</button>
    </div>
    <div class="upload-tip">
      只能上传JPG/PNG/JPEG/WEBP文件, 且大小不能超过500kb
    </div>
  </section>

  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/qs/6.10.1/qs.js"></script>
  <script src="./request.js"></script>
  <script>
    let uploadContainer = document.querySelector('.upload-container'),
      uploadInp = uploadContainer.querySelector('[name=upload-inp]'),
      uploadBtn = uploadContainer.querySelector('.upload-btn'),
      uploadList = uploadContainer.querySelector('.upload-list'),
      select = uploadBtn.querySelector('.select'),
      _file = null

    // 点击上传文件按钮, 触发input的点击事件
    select.addEventListener('click', function () {
      if (isDisabled()) {
        // 按钮禁用
        return
      }

      if (_file) {
        alert('一次只能上传一张图片~')
        return
      }

      uploadInp.click()
    })

    // 禁用按钮
    function isDisabled () {
      return select.classList.contains('disabled')
    }

    function img2Base64 (file) {
      return new Promise((resolve, reject) => {
        let fileReader = new FileReader
        fileReader.readAsDataURL(file) // => 会异步转化成Base64 => Promise封装
        fileReader.onload = function (event) {
          // 转化结果保存在event.target.result中
          resolve(event.target.result)
        }
      })
    }

    // 选择图片时的处理
    uploadInp.addEventListener('change', async function () {
      _file = this.files[0]

      if (!_file) {
        return
      }

      // 限制图片类型
      if (!/(jpg|png|jpeg|webp)/i.test(_file.type)) {
        alert('上传的图片格式不正确~')
        return
      }

      // 限制文件大小
      if (_file.size > 500 * 1024) {
        alert('文件太大了~')
        return
      }

      select.classList.add('disabled')

      let base64 = await img2Base64(_file)

      try {
        let data = await instance.post('/upload-single-base64', 
          {
            file: encodeURIComponent(base64), // 处理特殊字符
            filename: _file.name
          }, 
          {
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded'
            }
          }
        )

        if (data.status === 0) {
          alert('文件上传成功')
        } else {
          // status不为0, 走失败
          throw data.statusText
        }
      } catch (error) {
        // await失败 / try中主动/被动抛错才会走catch
        alert('文件上传失败~')
      } finally {
        select.classList.remove('disabled')
        _file = null
        uploadInp.value = ''
      }
    })
  </script>
</body>
</html>