JS预览图片,上传图片

JS选择图片(单图/多图)然后预览图片的总结
JQ使用 FormData 上传图片报错 jquery-3.1.1.min.js:4 Uncaught (in promise) TypeError: Illegal invocation
JQ使用 FormData 上传图片的时候参数显示的不是预期的值(下面有图)

JS选择图片预览

预览单图

根据上传的图片文件对象,转换为base64,然后赋值到页面上即可渲染

<input id="upload-file" type="file" accept="image/gif,image/jpeg,image/jpg,image/png,image/svg" />

<script>
    var uploadFile = document.getElementById('upload-file')

    uploadFile.onchange = function(e) {
        previewFile(e.target.files[0]).then(res => {
            console.log(res) // base64图片
        })
    }

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

            render.onerror = function() {
                reject({
                    msg: '转换图片失败'
                })
            }
        })
    }
</script>

预览多图

选择多图只需要在input添加一个 multiple 属性
选择多图后使用Promise.all来控制多图渲染的异步

<input id="upload-file" type="file" multiple accept="image/gif,image/jpeg,image/jpg,image/png,image/svg" />

<script>
    var uploadFile = document.getElementById('upload-file')
    uploadFile.onchange = function(e) {
        // e.target.files 是一个Object对象,无法直接使用map
        // 所以使用Object.values 获取对象中每一项的值
        // 配合 Promisie.all进行转换图片预览
        Promise.all(Object.values(e.target.files).map(item => previewFile(item))).then(res => {
            console.log(res) // [base64,base64] 转换结果为选择的图片数组
        })
    }

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

JS上传文件的坑

问题1: jquery-3.1.1.min.js:4 Uncaught (in promise) TypeError: Illegal invocation

附上复现的代码

// 后端接收的参数名称为 file
// file 对象为刚才上面选择的 file
var uploadFile = document.getElementById
var imgFile = uploadFile.files[0]

let formData = new FormData()
formData.append("file", imgFile)

$.ajax({
    url: "[要上传的接口路径]",
    type: "POST",
    dataType: "JSON",
    data: formData,
    success: res => {},
    fail: res => {}
})

问题出在了参数处理的部分,毕竟我们上传的是二进制流文件,所以我们要告诉JQ,不要转换我们的参数,让他保持为二进制格式。多加一个 processData:false

于是代码改成:

// 后端接收的参数名称为 file
// file 对象为刚才上面选择的 file
var uploadFile = document.getElementById
var imgFile = uploadFile.files[0]

let formData = new FormData()
formData.append("file", imgFile)

$.ajax({

    url: "[要上传的接口路径]",
    type: "POST",
    dataType: "JSON",
    data: formData,
    processData: false, // 增加这一行,不处理参数
    success: res => {},
    fail: res => {}
})

问题1解决,那很快就会引来问题2

问题2 上传的时候参数不对

就像这样

在这里插入图片描述

如果参数是这样传过去的,后端是接受不到图片的
因为JQ自动的帮我们设置了请求头,但是ajax2.0中不需要设置请求头,我们找到contentType,把它的值设为false就能够取消掉这个设置。

最后代码改成这样

// 后端接收的参数名称为 file
// file 对象为刚才上面选择的 file
var uploadFile = document.getElementById
var imgFile = uploadFile.files[0]

let formData = new FormData()
formData.append("file", imgFile)

$.ajax({

    url: "[要上传的接口路径]",
    type: "POST",
    dataType: "JSON",
    data: formData,
    contentType: false,
    processData: false, // 增加这一行,不处理参数
    success: res => {},
    fail: res => {}
})

上传问题解决~

发布了71 篇原创文章 · 获赞 58 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/Jioho_chen/article/details/103540508