zoukankan      html  css  js  c++  java
  • 前端图片上传的方式

    html

    type="file"指定input为文件选择框,accept="image/*"表示文件框可以选择图片,multiple表示可以选择多个文件。

    <input id="upload" type="file" accept="image/*,audio/*,video/*" multiple onfocus="this.blur()"/>
    

    capture拍照

    capture='camera'表示图片只能从相机实时抓取,禁止从相册中选择,需要注意的是capture和multiple同时使用时multiple会失效。

    onfocus防止键盘弹出

    onfocus="this.blur()"表示强制失去焦点,为了防止在某些手机浏览器上点击时会弹出键盘选择。

    change事件

    var upload = document.getElementById('upload');
    upload.addEventListener('change', function() {
      var file = upload.files[0];  //获取file文件
      console.info(file);
      console.info(file.size);
    }, false);
    

    file对象

    File对象为获取的文件对象,虽然有 getAsBinary()、getAsDataURL()和getAsText三个函数,但这个都是非标准函数,不能使用,需要使用FileReader读取文件。

    FileReader

    1) readAsArrayBuffer():在返回的result属性中将包含一个ArrayBuffer对象【缓冲数组,是一种用于呈现通用、固定长度的二进制数据的类型】以表示所读取文件的内容。

    2) readAsBinaryString():result属性中将包含所读取文件的原始二进制数据。

    3) readAsDataURL():result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容,即Base64。

    4) readAsText():result属性中将包含一个字符串以表示所读取的文件内容。

    图片转base64

    var reader = new FileReader();
    reader.readAsDataURL(file);   //文件读取为base64
    reader.onload = function(e) {
        //e代表事件,可以通过e.target获取FileReader对象然后在获取readAsDataURL读取的base64字符
        console.log(e.target.result);  ////this代表FileReader,可以用this.result获取读取结果
        //预览图片
        var img = new Image();
        img.src = this.result;
        $('#previewDIv').append(img);
    };
    

    URL对象

    blob 其实是 h5 表征的 Blob 对象数据, 可以使用Blob对象隐藏真实的资源路径,在一定程度上可以起到数据的加密性,更多的是为了干扰爬虫。

    日常使用的一些音频,视频,图片,我们都可以使用其Blob二进制数据流来表征数据,而非使用uri,就像经常用到的image sr 的dataUrl。

    var url = URL.createObjectURL(file);
    var img = new Image();
    img.src = url;
    img.onload = function(e) {
      window.URL.revokeObjectURL(this.src); //销毁
    }
    console.log(url);
    

    预览前端选择的文件

    var img = new Image();
    img.width = 200;
    img.height = 200;
    img.onload = function(){
    	window.URL.revokeObjectURL(img.src);  //释放通过URL.createObjectURL()创建的URL对象
    }
    img.src = window.URL.createObjectURL(file);   //用file对象创建blob协议的URL,用new Blob([file])
    $('#preview').append(img);
    

    Blob对象

    Blob(binary large object)对象代表了一段二进制数据,就是一个包含只读原始数据的类文件对象。

    File接口基于Blob,继承了Blob的功能,并且扩展支持了用户计算机上的本地文件。

    Blob构造函数生成文件

    var blob = new Blob(["pwstrick"]);    //数组中添加DOMString对象
    var a = document.createElement("a");
    a.href = URL.createObjectURL(blob);  //创建URL对象
    a.download = "test.txt";   //HTML5新属性,下载url的资源而不是导航,可以设置下载文件名
    a.textContent = "下载";    //a标签的文字
    document.getElementsByTagName('body')[0].appendChild(a);
    

    Blob构造函数生成图片

    var blob = new Blob([file]);    //数组中添加表单中获取的file文件
    var a = document.createElement("a");
    a.href = URL.createObjectURL(blob);  //创建URL对象
    a.download = "test.jpg";   //HTML5新属性,下载url的资源而不是导航,可以设置下载文件名
    a.textContent = "下载";    //a标签的文字
    document.getElementsByTagName('body')[0].appendChild(a);
    

    切割blob

    //返回文件某一段的blob
    function segment(file, start, end) {
        var reader = new FileReader();
        reader.onload = function(evt) {
            console.log(['Read bytes: ', start, ' - ', end].join(''));
            //console.info(this.result);  //文件的某一部分
        };
        var blob = file.slice(start, end);  //返回一个新的Blob对象,它包含有源Blob对象中指定范围内的数据
        return reader.readAsBinaryString(blob);   //FileReader读取blob对象
    }
    
    //切割某个文件
    var start = 0;  //读取起始位置
    var chunk = 1024 * 1000; //10KB
    var end = start + chunk;
    var size = file.size;  //最大位置
    while (start < size) {
        var b = segment(file, start, end);
        
        start = end;
        end = start + chunk;
        if (end > size) {
            end = size;
        }
    }
    

    FormData

    用FormData对象,可以使用键值对来模拟一个完整的表单,然后使用XMLHttpRequest发送这个"表单"。

    使用FormData的最大优点是可以异步上传一个二进制文件。

    var formData = new FormData();
    formData.append("name", "value"); //普通键值对
    formData.append("blob", blob); //传递一个blob对象,这里要用定制接口,不然后台保存的就是一个名为blob的文件
    formData.append("file", file); //传递一个file对象
    
    var oReq = new XMLHttpRequest();
    oReq.open("POST", "./uploadController/upload");
    oReq.onloadend = function () {  //请求结束时调用(包括成功:onload、失败:onabort、onerror)
        console.info(oReq.responseText);  //打印请求返回结果
        var jsondata = JSON.parse(oReq.responseText);  //转换为json对象
    }
    oReq.send(formData);  //发送表单
    

    移动端图片上传

    前端

    html

    <%--上传文件后返回的图片路径--%>
    <input hidden id="imgs" name="imgpath" value="${w.imgpath}">
    <%--file输入框,为了美化这里隐藏file输入框,用a标签触发file点击事件--%>
    <input hidden type="file" id="sceneImg" multiple capture='camera' accept='image/*'>  
    <%--拍照后预览图片--%>
    <div id="preview" style="display:inline-block">
        <%--显示时加载图片--%>
        <c:forTokens items="${w.imgpath}" delims="," var="path">
            <img src="./${path}" style=" 50px;height: 50px;margin-top:5px;">
        </c:forTokens>
    </div>
    <%--美化拍照按钮,用一张带链接的图片去触发file输入框的click事件--%>
    <a onclick='javascript:$("#sceneImg").click();'><img width="50px" height="50px" src="./asset/images/plus.jpg"></a>
    

    js

    $(function () {
    
        //拍照完毕时触发input-file的change事件
        var sceneImg = document.getElementById("sceneImg");
        sceneImg.addEventListener("change",function () {
            var file = sceneImg.files[0];  //获取到刚才拍照的图片
            //预览框中添加预览图片
            var img = new Image();
            /*img.width = 50;
            img.height = 50;*/
            img.style=" 50px;height: 50px;margin-top:5px";
            img.onload = function(){
                window.URL.revokeObjectURL(img.src);   //释放通过URL.createObjectURL()创建的URL对象
            }
            img.src = window.URL.createObjectURL(file);  //用blobURL的方式回显
            $('#preview').append(img);
            $('#preview').append(" ");
    
            /*判断图片路径是否超过指定长度*/
            if($('#imgs').val().length>450){
                layer.alert("图片以达上线,禁止添加!!!",{title:'提示',offset: '150px',icon: 2});
                return false;
            }
    
            /*上传照片*/
            var formData = new FormData();
            //添加字符串参数,这里是图片即将上传的文件夹
            formData.append("pathfolder",'img-'+'${handlercode}');
            //添加文件参数,这里也可以用blob
            formData.append('file', file);
            var oReq = new XMLHttpRequest();
            oReq.open("POST", "./uploadController/upload");
            oReq.onloadend = function () {  //请求结束时调用(包括成功:onload、失败:onabort、onerror)
                var jsondata = JSON.parse(oReq.responseText);  //解析后端返回的json
                var imgPath = jsondata.path;
                var oldimgs = $('#imgs').val();
                /*成功后把图片路径加到input框中*/
                if(oldimgs.length>0){
                    $('#imgs').val(oldimgs+","+imgPath);
                }else {
                    $('#imgs').val(imgPath);
                }
            }
            oReq.send(formData);  //提交表单
        });
    });
    

    后端

    package com.gmtx.common.controller;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URLEncoder;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    
    /**
     * UploadController
     * @author: 秋雨
     * 2021-02-01 16:32
     **/
    @Controller
    @RequestMapping(value = "/uploadController", method = { RequestMethod.GET,RequestMethod.POST })
    public class UploadController {
    
        /**
         * 上传文件
         * @param req
         * @param resp
         * @return
         * @throws Exception
         */
        @RequestMapping(value = "/upload", method = {RequestMethod.POST })
        public String Upload(HttpServletRequest req, HttpServletResponse resp)throws Exception{
            req.setCharacterEncoding("utf-8");
            List<MultipartFile> files = ((MultipartHttpServletRequest) req).getFiles("file");
            MultipartFile file = files.get(0);
            String pathfolder = req.getParameter("pathfolder");
    
            if (file.isEmpty()) {
                String json = "{"success":false,"message":"file is empty!"}";
                resp.getOutputStream().write(json.getBytes("utf-8"));
            } else {
                Date time =new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                String dateNowStr = sdf.format(time);
                //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
                String folderPath = File.separator+"upload"+File.separator+pathfolder+File.separator+dateNowStr;
                String savePath = req.getSession().getServletContext().getRealPath(folderPath);
                File fileFolder = new File(savePath);
                //判断上传文件的保存目录是否存在
                if (!fileFolder.exists() && !fileFolder.isDirectory()) {
                    //创建目录
                    fileFolder.mkdirs();
                }
                //文件保存目录
                String filesavepath = savePath+File.separator+file.getOriginalFilename();
    
                //IO流写入
                OutputStream outputStream=new FileOutputStream(filesavepath);
                InputStream inputStream = file.getInputStream();
                //FileUtil.copyStream(inputStream, outputStream);
                byte[] bytes = new byte[1024];
                int len = 0;
                while((len = inputStream.read(bytes))!=-1){    //读取到文件末尾的话可以读到-1
                    outputStream.write(bytes,0,len);
                }
                //flush输出流
                outputStream.flush();
                //关闭流文件
                inputStream.close();
                outputStream.close();
    
                //图片存储路径(web用)
                String webPath = folderPath+File.separator+file.getOriginalFilename();
                //因为URLEncoder.encode会把空格改为+号,要手动把加号改为%20
                webPath = URLEncoder.encode(webPath,"utf-8").replace("+", "%20");
                String json = "{"success":true,"message":"文件上传成功!","path":""+ webPath +""}";
    
                resp.resetBuffer();
                resp.setContentType("text/html;charset=UTF-8");
                resp.getOutputStream().write(json.getBytes("utf-8"));
                resp.getOutputStream().flush();
            }
            return null;
        }
    }
    

    参考

    https://www.cnblogs.com/hehuiself/p/7099861.html

    如果这篇文章对你有用,麻烦关注一下本人微信公众号,关注送福利哦~
    微信公众号二维码
    不定期安利各种插件,编程技巧,编程思想,欢迎交流~
  • 相关阅读:
    react中refs的使用
    在npm发布自己造的轮子
    如何阅读一本书——分析阅读模板
    如何阅读一本书——检视阅读模板
    Redis教程——检视阅读
    如何阅读一本书——分析阅读Pre
    SVN常用功能介绍(二)
    SVN常用功能介绍(一)
    分页sql大全
    .NetCore 登录(密码盐+随机数)
  • 原文地址:https://www.cnblogs.com/aeolian/p/14357856.html
Copyright © 2011-2022 走看看