原生js复制粘贴上传图片前后台代码,兼容firebox,chrome, ie11,亲测有效

需求:粘贴上传图片,截图工具,右键粘贴,或者ctrl+v粘贴

方法1:可直接套用富文本框的图片上传功能,完成复制粘贴

缺点:麻烦,样式难控制

方法2:用原生js完成,以下案例基于此,样式请自己动手调整

 

用js完成请注意收下几点:

1、前端传回去给后台是base64流,后台要将接收的base64转换成图片保存,记住不是二进制流,是base64位

 

 

 

2、editorWenban是可编辑的文本框,用以复制粘贴图片,tar_box是用来曾现图片的

 

前端代码如下:

<!DOCTYPE html>
<html lang="UTF-8">
<head>
    <meta charset="UTF-8">
    <title>测试测试</title>
</head>

<style>
    body {
        display: -webkit-flex;
        display: flex;
        -webkit-justify-content: center;
        justify-content: center;
    }
    #tar_box {
        width: 500px;
        height: 500px;
        border: 1px solid red;
    }

    #editorWenban img{
        display: none;
    }

    #tar_box img{
        width: 120px;
        height: 120px;
        margin:20px;
        border: 1px solid #5a7710;
    }
</style>

<body>

<div contenteditable style="width: 100px;height: 100px; border:1px solid" id="editorWenban">
</div>

<div id="tar_box">
    <!--<img src="" style=""/>-->
</div>

<script>
    document.addEventListener('paste', function (event) {
        console.log(event)
        var isChrome = false;
        if ( event.clipboardData || event.originalEvent ) {
            //not for ie11  某些chrome版本使用的是event.originalEvent
            var clipboardData = (event.clipboardData || event.originalEvent.clipboardData);
            if ( clipboardData.items ) {
                // for chrome
                var  items = clipboardData.items,
                    len = items.length,
                    blob = null;
                isChrome = true;
                //items.length比较有意思,初步判断是根据mime类型来的,即有几种mime类型,长度就是几(待验证)
                //如果粘贴纯文本,那么len=1,如果粘贴网页图片,len=2, items[0].type = 'text/plain', items[1].type = 'image/*'
                //如果使用截图工具粘贴图片,len=1, items[0].type = 'image/png'
                //如果粘贴纯文本+HTML,len=2, items[0].type = 'text/plain', items[1].type = 'text/html'
                // console.log('len:' + len);
                // console.log(items[0]);
                // console.log(items[1]);
                // console.log( 'items[0] kind:', items[0].kind );
                // console.log( 'items[0] MIME type:', items[0].type );
                // console.log( 'items[1] kind:', items[1].kind );
                // console.log( 'items[1] MIME type:', items[1].type );

                //阻止默认行为即不让剪贴板内容在div中显示出来
                event.preventDefault();

                //在items里找粘贴的image,据上面分析,需要循环
                for (var i = 0; i < len; i++) {
                    if (items[i].type.indexOf("image") !== -1) {
                        // console.log(items[i]);
                        // console.log( typeof (items[i]));

                        //getAsFile() 此方法只是living standard firefox ie11 并不支持
                        blob = items[i].getAsFile();
                    }
                }
                if ( blob !== null ) {
                    var reader = new FileReader();
                    reader.onload = function (event) {
                        // event.target.result 即为图片的Base64编码字符串
                        var base64_str = event.target.result
                        //可以在这里写上传逻辑 直接将base64编码的字符串上传(可以尝试传入blob对象,看看后台程序能否解析)
                        uploadImgFromPaste(base64_str, 'paste', isChrome);
                    }
                    reader.readAsDataURL(blob);
                }
            } else {
                //for firefox
                setTimeout(function () {
                    //设置setTimeout的原因是为了保证图片先插入到div里,然后去获取值
                    var imgList = document.querySelectorAll('#editorWenban img'),
                        len = imgList.length,
                        src_str = '',
                        i;
                    for ( i = 0; i < len; i ++ ) {
                        if ( imgList[i].className !== 'my_img' ) {
                            //如果是截图那么src_str就是base64 如果是复制的其他网页图片那么src_str就是此图片在别人服务器的地址
                            src_str = imgList[i].src;
                        }
                    }
                    uploadImgFromPaste(src_str, 'paste', isChrome);

                    //var box = document.getElementById("#editorWenban");
                    //找到子元素
                    //var img=document.getElementsByTagName("#editorWenban img");
                    //console.log("imgimgimgimg",img)
                    //box.removeChild(img);
                }, 1);

            }
        } else {
            //for ie11
            setTimeout(function () {

                //document.getElementById("#editorWenban")
                var imgList = document.querySelectorAll('#editorWenban img'),
                    len = imgList.length,
                    src_str = '',
                    i;
                for ( i = 0; i < len; i ++ ) {
                    if ( imgList[i].className !== 'my_img' ) {
                        src_str = imgList[i].src;
                    }
                }
                uploadImgFromPaste(src_str, 'paste', isChrome);
            }, 1);
        }
    })

    function uploadImgFromPaste (file, type, isChrome) {
        console.log("file=============",file)
        var formData = new FormData();
        formData.append('imgByte', file);
        formData.append('submission-type', type);

        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://127.0.0.1:8555/weChatHandleTask/saveToImgByStr',true);
        xhr.onload = function () {
            if ( xhr.readyState === 4 ) {
                if ( xhr.status === 200 ) {

                    var data = xhr.responseText;
                    var tarBox = document.getElementById('tar_box');
                    var img = document.createElement('img');
                    img.className = 'my_img';
                    img.src = 'http://127.0.0.1:8555/test/'+data;
                    //ie不生效,所以直接在样式中测试
                    img.style = 'width: 120px; height: 120px; margin:20px;border: 1px solid #5a7710;';
                    tarBox.appendChild(img);

                } else {
                    console.log( xhr.statusText );
                }
            };
        };
        xhr.onerror = function (e) {
            console.log( xhr.statusText );
        }
        xhr.send(formData);
    }

</script>

</body>
</html>

 

 

后台代码是springboot写的,如下:

 

/**
     * 将接收的base64转换成图片保存
     *
     * @param imgByte
     * base64数据
     * @param cardNum
     * 号码
     * @return 成功返回图片保存路径,失败返回false
     */
    @RequestMapping("/saveToImgByStr")
    @ResponseBody
    public Object saveToImgByStr(String imgByte, String cardNum, HttpServletRequest request, HttpServletResponse response) throws IOException {

        System.out.println("imgByte====="+imgByte);
        String destDir = "F:\\ScgStaticPath\\test";

        if(imgByte.indexOf("data:image/png;base64") > -1){
            imgByte=imgByte.replaceAll("data:image/png;base64,","");
            BASE64Decoder decoder =  new BASE64Decoder();
            byte[] imageByte = null;
            try{
                imageByte = decoder.decodeBuffer(imgByte);
                for (int i = 0; i < imageByte.length; ++i) {
                    // 调整异常数据
                    if (imageByte[i] < 0) {
                        imageByte[i] += 256;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (imageByte.length>0) {
                try {
                    //获取文件上传的真实路径
                    //String uploadPath = request.getSession().getServletContext().getRealPath("/");

                    SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
                    String createNewDirStr = fmt.format(new Date());

                    //保存文件的路径
                    String filepath = destDir + File.separator + createNewDirStr;

                    File destfile = new File (filepath);

                    if (!destfile.exists()) {
                        destfile.mkdirs();
                    }
                    //文件新名称
                    String fileNameNew = getFileNameNew() + ".png";
                    File f = new File(destfile.getAbsoluteFile() + File.separator + fileNameNew);
                    // 将字符串转换成二进制,用于显示图片
                    // 将上面生成的图片格式字符串 imgStr,还原成图片显示
                    InputStream in = new ByteArrayInputStream(imageByte);
                    FileOutputStream fos = new FileOutputStream(f);
                    // BufferedOutputStream bos = new BufferedOutputStream(fos);
                    byte[] buf = new byte[1024];
                    int length;
                    length = in.read(buf, 0, buf.length);

                    while (length != -1) {
                        fos.write(buf,0,length);
                        length = in.read(buf);
                    }
                    fos.flush();
                    fos.close();
                    in.close();
                    //String lastpath = filepath + File.separator + fileNameNew;
                    String lastpath = createNewDirStr + File.separator + fileNameNew;
                    System.out.println("返回图片路径:" + lastpath);
                    return lastpath;

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }
        }else{

            ServletInputStream inputStream = request.getInputStream();

            //获取文件上传的真实路径
            //String uploadPath = request.getSession().getServletContext().getRealPath("/");

            SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
            String createNewDirStr = fmt.format(new Date());

            //保存文件的路径
            String filepath = destDir + File.separator + createNewDirStr;
            File destfile = new File( filepath);
            if (!destfile.exists()) {
                destfile.mkdirs();
            }
            //文件新名称
            String fileNameNew = getFileNameNew() + ".png";
            File f = new File(destfile.getAbsoluteFile() + File.separator + fileNameNew);
            if (!f.exists()) {
                OutputStream os = new FileOutputStream(f);
                BufferedOutputStream bos = new BufferedOutputStream(os);

                byte[] buf = new byte[1024];
                int length;
                length = inputStream.read(buf, 0, buf.length);

                while (length != -1) {
                    bos.write(buf, 0, length);
                    length = inputStream.read(buf);
                }
                bos.close();
                os.close();
                inputStream.close();
                //String lastpath = filepath + File.separator + fileNameNew;
                String lastpath = createNewDirStr + File.separator + fileNameNew;
                System.out.println("返回图片路径:" + lastpath);
                return lastpath;
            }
        }


        return false;
    }


    /**
     * 为文件重新命名,命名规则为当前系统时间毫秒数
     *
     * @return string
     */
    private String getFileNameNew() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return fmt.format(new Date());
    }

    /**
     * 以当前日期为名,创建新文件夹
     *
     * @return
     */
    private String createNewDir() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
        return fmt.format(new Date());
    }

 

 

 

 

测试完成效果图:

 

 

 

 

 

 

 

posted @ 2019-11-18 16:42  柠檬仔啊  阅读(831)  评论(0编辑  收藏  举报