JavaScript 云鸠自学笔记专区—002 限制上传的文件类型

y9info · 2021年12月14日 · 最后由 handletaiga 回复于 2023年08月10日 · 328 次阅读

问题描述:

前端使用 form 上传文件,要求限定上传的格式为图片。 改进前使用 accept:来限制文件类型,但是发觉这种限制比较弱,用户选择其他格式文件后,仍然可以提交非图片格式的文件到后端。

<%= form.file_field :tm_image, multiple:false,class:"form-control ",style:"width:300px;", accept:'image/png,image/gif,image/jpeg,image/jpg,image/tiff,image/bmp,image/svg' %>

解决方案:

解决方案分两个小点,一个是读取用户选取的文件的文件格式并判断是否图片格式,另一个是,在非图片文件格式时,提示用户。

1. JavaScript 代码如下


<script type="text/javascript">

  function checkImage(img) {
              const realFileElement = document.querySelector("#realFileType");      //这里的realFileElement元素,对应为上述form中的input框下面为提示建立的div
              const file = img.files[0]    ///读取用户选取的文件
              var filePath = img.value;  ///读取用户选取的文件的路径
              var fileExt = filePath.substring(filePath.lastIndexOf("."))
                  .toLowerCase();  ///截取用户选取的文件的后缀名

              if (!checkFileExt(fileExt)) {          ///如果文件后缀名检测不是图片 
                  realFileElement.innerText = `所选“${file.name}”文件不是图片,请选择图片!`;   ///innerText 方法,在提示div区域写入提示内容
                  img.value = "";  ///同时将input框的value设置为空,因为文件后缀名不是图片
                  return;
              }
          } 
  function checkFileExt(ext) {            ///检测后缀名是否为图片格式的函数
      if (ext.match(/.jpg|.gif|.png|.bmp|.jpeg|.tiff|.svg/i)) {
          return true;
      }
      return false;
  }

</script>

2.将函数嵌入 form,在 file input 中增加:onchange,变更后的 form 如下:

<%= form.file_field :tm_image, multiple:false,class:"form-control ",style:"width:300px;", accept:'image/png,image/gif,image/jpeg,image/jpg,image/tiff,image/bmp,image/svg',:onchange => "checkImage(this)" %>

3.在 input 框下面增加提示的 div

///通过其他方式提示也可以,譬如 alert,但 alert 提示个人感觉,用户处理时需要移动眼球和鼠标,不如这种提示方法感知度好。

<div class="text-red" id="realFileType"></div>   ///这里的 id="realFileType",对应的是上述JavaScript函数中的 const realFileElement = document.querySelector("#realFileType"); 

说明

上述 JavaScript 函数通过读取用户选取的文件的后缀名来判断文件类型,存在一定的不足,譬如可以通过修改虚假的文件名后缀来骗过上述函数,用户可以手动修改文件后缀名以绕过格式限制,从而上传成功。上述方案的优点是,代码简单,不需要了解太高深的文件类型二进制数据判断知识,JavaScript 小白也能读懂,一般场景下对文件类型校验没有太高要求的,应用也基本足够。 更完善的解决方法是,读取文件二进制数据中的文件签名来精准判断文件类型,详见https://github.com/jealyn/real-file-type

上述方法,稍作改动也可以用于判断 docx、pdf 等格式,也能增加文件大小的判断,需要增加代码也不多。

@eggy car, It's great to be here with everyone; I've learned a lot from your contributions, and I want to express my gratitude. In the preceding JavaScript code, the file extension is read to determine the file type.

需要 登录 后方可回复, 如果你还没有账号请 注册新账号