前言:
适合人群:刚起步的前端新人。(前后端未分离的项目)全栈后端老大哥的前端需求(点名批评下jsp)。
解决问题:
1.普通js上传一张图片
2.普通js上传一张图片,提前预览。然后再决定是否上传。
3.普通js一次上传多张图片。
复制代码
知识点:
* FormData对象的使用(上传图片)
* FileReader对象的使用(转换成base64可被预览)
复制代码
1.普通js上传一张图片
HTML代码:
需要一个input:file图片上传控件
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代码:
多了一个图片标签
type="file" class="file" name="file" />
"" 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代码:
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
如有错误,欢迎指正!
当然有兴趣大家也可以一起交流,学习(群里有大佬,欢迎活跃的同学)!
打个广告,贴个二维码!