阅读 2553

原生JS上传图片(FormData,可预览,一次多图)

前言:

适合人群:刚起步的前端新人。(前后端未分离的项目)全栈后端老大哥的前端需求(点名批评下jsp)。

解决问题:

1.普通js上传一张图片

2.普通js上传一张图片,提前预览。然后再决定是否上传。

3.普通js一次上传多张图片。
复制代码

知识点:

* FormData对象的使用(上传图片)
* FileReader对象的使用(转换成base64可被预览)
复制代码

1.普通js上传一张图片

HTML代码:

需要一个input:file图片上传控件

 <input type="file" class="file" name="file" />
复制代码

JS代码:

1.绑定change事件,这样上传点击上传的图片就可以获取到

2.注意你可能会拿到这个

别慌。因为对象的特殊,file对象是不会被开发人员所直接捕获(可见)的。但确实存在。

这个对象有一个files属性,返回的就是FileList对象。FileList对象看起来和数组一样,但不是数组,不能使用forEach,但是有length属性

可以通过FileList.item(0) 或 FileList[0] 获取对应的第1个file对象

3.将单个图片对象放到FormData中。使用FormData的append方法。

注意: 对于加入图片对象时: append()方法强烈建议使用三个参数的方法(2个参数的传递图片时,可能出现问题)。分别是 (键名,图片对象,图片名称)

普通的键值对可以使用append(key,value)即可

4.完成了,就是这么简单。使用你熟悉的jq/axios/自己封装的ajax发到后台吧。

    document.querySelector('.file').addEventListener('change', function(e) {
          //1.可以通过this拿到这个file的DOM元素
          console.log(this)
          //1.  e 函数事件参数对象中也有这个file的DOM元素对象。使用e.target也可以直接拿到
          console.log(e.target)
          //对开发人员屏蔽,所以直接 必须调用这个文件的DOM对象的files属性,返回一个数组
          let files = e.target.files
          console.log(files)
          // console.log(files.item(0))
          // console.log(files[0])
          // 判断一手是否有文件
          if (!files.length) return
          // 上传文件 创建FormData
          let formData = new FormData()
          // upFile就是后台接收的key
          formData.append('upFile', files[0], files[0].name)
          // 将formdata发送到后台即可
          // 我用的 axios.post('url', formData)
        })
复制代码

2.普通js上传一张图片,提前预览。然后再决定是否上传

相比上面那个一键上传的功能,不能预览的功能你很不爽吧。很多时候就是要先预览下本地的图片,但是还不能上传到图片服务器占内存....

HTML代码:

多了一个图片标签

<input type="file" class="file" name="file" />
<img src="" alt="" />
复制代码

JS代码: 直接提供一个将file对象转base64方法。你只需要在获取file对象后,先不着急封装到FormData中,先转base64看看效果,再做接下来操作

 
        /*
         * 将file对象转化为base64编码
         * file  目标file对象
         */
        function previewFile(file) {
          let reader
          if (file) {
            // 创建流对象
            reader = new FileReader()
            reader.readAsDataURL(file)
          }
          // 捕获 转换完毕
          reader.onload = function(e) {
            // 转换后的base64就在e.target.result里面,直接放到img标签的src属性即可
            document.querySelector('img').src = e.target.result
          }
        }
复制代码

3.普通js一次上传多张图片。

大概是这个样子,用户可以按住Ctrl或Shift可以一次选择多张。

1.HTML的input:file控件中多一个multiple属性

HTML代码:

<input type="file" class="file" name="file" multiple="multiple" />
复制代码

JS代码:

这里需要注意下的是FormData的append方法。相同的key,是会自动追加的,并不会覆盖,但注意需要使用getAll()才能完整获取查看,get()和querySelector只获取第一个类似

获取到的formData中file数组是这个效果

    document.querySelector('.file').addEventListener('change', function(e) {
          let files = e.target.files
          if (!files.length) return
          // 上传文件 创建FormData
          let formData = new FormData()
          // 遍历FileList对象,拿到多个图片对象
          for (let i = 0; i < files.length; i++) {
            // formData中的append方法 如果已有相同的键,则会追加成为一个数组  注意:这里需要使用formData.getAll()获取
            formData.append('upFile', files[i], files[i].name)
          }
          console.log(formData.getAll('upFile'))
          // 将formdata发送到后台即可
          // 我用的 axios.post('url', formData)
        })
复制代码

总结:

1.总体来说就是一些API的使用,另外还需要注意一些细节,例如判定该file对象是否是图片,判定图片的类型、大小等。可在file对象的 属性查看。

2.本文的传输方式统一采用ajax异步,如需采用原生表单同步发送,只需要在FORM属性上加一个enctype="multipart/form-data" 即可

3.关于图片相关的还有一个压缩也是个重要问题(很多时候上传都是由大小限制的)。这个暂时没有总结...大体是canvas压缩,大家可以根据需要自行搜一把,github上也有很多封装好的。

2019.6.13

如有错误,欢迎指正!

当然有兴趣大家也可以一起交流,学习(群里有大佬,欢迎活跃的同学)!

打个广告,贴个二维码!

关注下面的标签,发现更多相似文章
评论