盘点web文件上传的几种方式

本文主要讲“图片上传预览”、“html单文件上传"、“html多文件上传”、“使用VUE实现文件上传”、“文件下载”;

1、图片上传预览

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>图片上传预览</title>
    <script typet="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
    <script type="text/javascript">
        function showPreview(source) {
            var file = source.files[0];
            if(window.FileReader) {
                var fr = new FileReader();
                fr.onloadend = function(e) {
                    document.getElementById("portrait").src = e.target.result; //这个就是图片的流,可以直接展示到页面上
                };
                fr.readAsDataURL(file);
            }
        }
    </script>
</head>
<body>

<input type="file" name="file" onchange="showPreview(this)" />
<img id="portrait" src="" width="70" height="75">

</body>
</html>

2、单文件上传(使用ajax)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script typet="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
    <script>
        $(function(){
            $('#multiFile').change(function() {
                console.log(this.files);
                var file = this.files[0];
                var name = file.name;
                console.log(name);
                var size = file.size;
                var type = file.type;
                //your validation
                var formData = new FormData(file);//这个文件就是我们上传的数据
            });
            $('#file1').change(function() {
                console.log(this.files);
                var file = this.files[0];
                var name = file.name;
                console.log(name);
                var size = file.size;
                var type = file.type;
                //your validation
            });

        });

    </script>
</head>
<body>
<input id="multiFile"  name="uploadedfile" multiple="true"  accept=".xlsx,.xls,.txt" type="file"  />
<input id="file1"  name="uploadedfile"  accept=".xlsx,.xls,.txt" type="file"  />

</body>
</html>

**3、多文件使用form表单上传(使用ajax)

前端:**

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多文件上传</title>
    <script typet="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
    <script>
        function doUpload() {
            var formData = new FormData($("#uploadForm")[0]);
            console.log($("#uploadForm"));
            console.log(formData);
            $.ajax({
                url: '/shapeFile/upload',
                type: 'POST',
                data: formData,
                async: false,
                cache: false,
                contentType: false,
                processData: false,
                success: function (returndata) {
                    console.log(returndata);
                },
                error: function (returndata) {
                    alert(returndata);
                }
            });
        }
    </script>
</head>
<body>

<form id="uploadForm" enctype="multipart/form-data">
    <p >指定文件夹名: <input type="text" name="uploadDir" value= ""/></p >
    <p >上传文件: <input type="file" name="file"/></p>
    <p >上传文件: <input type="file" name="file2"/></p>
    <input type="button" value="上传" onclick="doUpload()" />
</form>

</body>
</html>

后台接收:

@RequestMapping(value="/upload",method = RequestMethod.POST)
    @CrossOrigin //跨域
    public Object getFile(HttpServletRequest request){
        /**
         下边这个是获取非文件的属性值方法
         **/
        String uploadDir= request.getParameter("uploadDir");
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
//        List<MultipartFile> fileList = multipartRequest.getFiles("file");
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        if(fileMap == null || fileMap.size() == 0){
            return new Myexception("请上传文件,注意文件的name属性为file");
        }
        Collection<MultipartFile> files = fileMap.values();
        for(MultipartFile file:files){
            /**
             注意这里获取的个数,是根据前端form表单里有几个,type=file来决定的,
             比如你虽然只点选了一个文件,上传,但这里实际上回有两个MultipartFile对 象,只不过其中一个MutipartFile的文件名会为空,这就是为什么下边会有个判断文件名
             为空的步骤**/
            String req= file.getOriginalFilename();
            if(StringUtils.isEmpty(req)){
                continue;
            }
            File tempFile = getTmpFile(req);
            System.out.println(tempFile.getAbsolutePath());
            if(!tempFile.exists()){
                tempFile.getParentFile().mkdirs();
                try {
                    tempFile.createNewFile();
                    file.transferTo(tempFile); //到这里tempFile即是上传上来的文件。
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(req);
        }
        return null;
    }
    /**
     下边这个是好方法
     **/
    public File getTmpFile(String fileName) {
        File tmpDir = FileUtils.getTempDirectory();//此处可以自定义上传文件放在哪里
        System.out.println("========"+tmpDir.getAbsolutePath());
        String tmpFileName = (Math.random() * 10000 + "").replace(".", "")+"_"+fileName;
        return new File(tmpDir, tmpFileName);
    }

4、form多文件上传(直接提交)

前端:**

  $("#fm").form("submit", {
                url: url,
                onSubmit: function () {
                    return $(this).form("validate");
                },
                success: function (result) {
                    $.messager.alert("系统提示", "保存成功");
                    resetValue();
                    $("#dlg").dialog("close");
                    $("#dg").datagrid("reload");
                }
            });
 
 <form id="fm"  method="post" enctype="multipart/form-data">
        <table cellspacing="8px">
            <tr>
                <td>商品名称:</td>
                <td><input type="text" id="goodsName" name="goodsName"
                           class="easyui-validatebox" required="true"/>&nbsp;<font
                        color="red">*</font>
                </td>
             
              <tr>
               <td>选择图片:</td>
               <td>
                <input id="goodsPicture" name="goodsPicture" type="file" />
                </td>
            </tr>
                          <tr>
               <td>选择图片:</td>
               <td>
                <input id="goodsPicture1" name="goodsPicture1" type="file"/>
                </td>
            </tr>
        
        </table>
    </form>
 

后台接收:(跟标题3中的方法大体一致)

CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
 
   //获取前台提交图片  
         if (multipartResolver.isMultipart(request)){  
             MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;  
              String filepath = "D:/test";
             Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
             String fileName = null;
             for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                 // 获取单个文件
                 MultipartFile mf = entity.getValue(); // 获得原始文件名
                 fileName = mf.getOriginalFilename(); // 截取文件类型; 这里可以根据文件类型进行判断
                 String fileType = fileName.substring(fileName.lastIndexOf('.'));
                 try {
                     // 截取上传的文件名称
                     String newFileName = fileName.substring(0, fileName.lastIndexOf('.'));
                     //图片转换成io,存到数据库
                     byte[] image = mf.getBytes();
                     // 拼接上传文件位置
                     goods.setImage(image);
                     goods.setImageName(newFileName);
                     goods.setImageType(fileType);
                    
                    
                    //保存到服务器
                     String newfilePath = filepath + File.separatorChar + newFileName + fileType;
                     System.out.println("拼接好的文件路径地址------------->>>>>>>>" + newfilePath);
                     // 重新组装文件路径,用于保存在list集合中
                     File dest = new File(filepath);
                     // 判断文件夹不存在就创建
                     if (!dest.exists()) {
                         dest.mkdirs();
                         }
                     // 创建文件实例
                     File uploadFile = new File(newfilePath);
                     // 判断文件已经存在,则删除该文件
                     if (uploadFile.exists()) {
                         uploadFile.delete();
                         }
                     } catch (Exception e) {
                         e.printStackTrace();
                 }
             }  
         }

5、vue中使用文件上传

在这里插入图片描述

我们是用ref=“”来定位dom,然后vue写法通过DOM取文件数据
前端:**

<div class="form-group" style="width:100%;">
            <div class="col-sm-2 control-label">安装包</div>
            <div class="col-sm-9" class="test">
                <a v-show="!showUpload" href="javascript:void(0);" class="upload" >选择文件 > <span>未选择任何文件</span>
                    <input id="upload" class="replyFileid" type="file"   @change="getfilename(this);" ref="inputer" style="width: 400px;"   />
                </a>
                <input  v-show="showUpload" type="text" class="form-control" :readonly="true"  v-model="version.fileName" />

            </div>
        </div>

自定义css:

        .upload {
            padding: 4px 10px;
            height: 20px;
            line-height: 20px;
            position: relative;
            text-decoration: none;
            color: #4d90d3;
            cursor: pointer;
        }
        .replyFileid{
            width:100%;
            position: absolute;
            overflow: hidden;
            right: 0;
            top: 0;
            filter:alpha(opacity=0);
            -moz-opacity:0;
            -khtml-opacity: 0;
            opacity: 0;
            cursor: pointer;
            text-decoration: none;
        }
        .upload span{
            color:#999;
            cursor: pointer;
        }
        a:link {
            text-decoration: none;
        }
        a:visited {
            text-decoration: none;
        }
        a:hover {
            text-decoration: none;
        }
        a:active {
            text-decoration: none;
        }

js中:

 getfilename (e) {
            let inputDOM = this.$refs.inputer;
            vm.file = inputDOM.files[0];// 通过DOM取文件数据
            //判断文件类型
            var filepath = inputDOM.files[0].name
            var extStart = filepath.lastIndexOf(".");
            var ext = filepath.substring(extStart, filepath.length).toUpperCase();
            if (ext != ".APK" && ext != ".EXE" && ext != ".JAR" ) {
                alert("文件限于apk,exe,jar格式");
                return ;
            }
            //判断文件大小
            var size = Math.floor(inputDOM.files[0].size / 1024/1024);//计算文件的大小 
            console.log(size);
            if(size>180){
                alert("上传文件过大,不得超过180M");
                return ;
            }
            this.formData=new FormData();//new一个formData事件
            this.formData.append("file",vm.file); //将file属性添加到formData里
            //此时formData就是我们要向后台传的参数了
            //返回文件名
            $('.upload span').html(vm.file.name);


        },

后台接收:

@RequestMapping("/upload")
    public BaseResponse upload(@RequestParam("file")MultipartFile file){
        BaseResponse response=new BaseResponse(StatusCode.Success);
        try{
            if(file.isEmpty()){
                response.setMsg("上传文件为空!");
                response.setCode(-1);
                return response;
            }
            String fileName = file.getOriginalFilename();
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            //设置文件存储路径
            String filePath = this.uploadPath;
            String randomPath = String.valueOf(new Date().getTime());
            filePath = filePath+randomPath+"/";
            String path = filePath + fileName;
            File dest = new File(path);
            //检测是否存在目录
            if(!dest.getParentFile().exists()){
                dest.getParentFile().mkdirs();//新建文件夹
            }
            file.transferTo(dest);//文件写入
            Map<String,Object> map = new HashMap<>();
            map.put("path",path);
            response.setData(map);
        }catch (Exception e){
            e.printStackTrace();
            response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
        }
        return response;
    }

拓展:
1、当上传文件过大时,需要在springboot中配置:

spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=200MB
spring.servlet.multipart.enabled=true

2、上传页面长时间等待,需要遮罩层:
在这里插入图片描述
遮罩层实现:(其实就是在页面最顶层追加了一个透明度高的div)

 //此处执行loading
                    var ele_id ="#operaterLayer"//需要遮罩的div
                    //添加遮罩元素
                    var mask = '<div class="mask" ele='+ele_id+' style="z-index: 99999999; width: '+780+'px !important; height: '+325+'px !important; left: '+$(ele_id).offset().left+'px !important; top: '+$(ele_id).offset().top+'px !important;"><div>数据加载中...</div></div>';
                    $("body").append(mask);
  //清除loading     
  $(".mask").remove();                                          

6、文件下载(浏览器直接访问下载)

    @RequestMapping(value = "/downloadFile",method = RequestMethod.GET)
    public void downLoad(HttpServletResponse response) throws Exception {
        File f = new File("e://Test/model01.txt");
        boolean isOnLine = false;
        if (!f.exists()) {
            response.sendError(404, "File not found!");
            return;
        }
        String fileName = f.getName();
        fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");

        BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
        byte[] buf = new byte[1024];
        int len = 0;
        response.reset(); // 非常重要
        if (isOnLine) { // 在线打开方式
            URL u = new URL("file:///" + "e://Test/model01.txt");
            response.setContentType(u.openConnection().getContentType());
            response.setHeader("Content-Disposition", "inline; filename=" + fileName);
            // 文件名应该编码成UTF-8
        } else { // 纯下载方式
            response.setContentType("application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        }
        OutputStream out = response.getOutputStream();
        while ((len = br.read(buf)) > 0)
            out.write(buf, 0, len);
        br.close();
        out.close();
    }
}

上边这个接口是一个文件下载的接口,主要有以下几个注意的:

filePath 参数,是在文件上传后,后台应该给你返回一个相对路径,比如/upload/2018-08-03/test.jpg 这样的字符串,接着你在调用这个图片下载接口时,可以直接传回来即可。
isOnLine 参数,这个其实为了方便前端对于下载的文件,是预览,还是下载 ,提供了两种选择,请注意,文件预览,必须是可预览的文件,比如doc 、xls 这种是浏览器无法预览的。传入true ,则会打开,传入false或者不传入这个参数,则只会下载。

     关于这个预览 、下载 多说几句,就是对于我们http 请求来说,文件的预览 、下载 ,其实对应于请求 中,是一个请求头设置 的问题,当然前提是这个文件可以被浏览器识别打开:

 response.setHeader("Content-Disposition", "inline; filename=" + fileName);
 response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

  • 如果是下载,那么上边为attachment。
  • 如果是预览,那么上边为inline。
      对于前端来说,其实图片的预览不需要关注这个,因为图片对于 等那种可以访问路径资源的标签,即使你设置的是下载 ,它也能自动打开,但是对于pdf ,貌似必须要在上边接口里,设置成预览 ,才能把它打开。

参考:https://blog.csdn.net/wohaqiyi/article/details/79179600

8、上传文件到项目静态目录中,而不是编译后的target里面

上传文件到两个不同的路径下,一个是项目路径,一个的项目编译路径,上传到编译路径下(target)文件可能会自动消失。

	@PostMapping("/uploadfile")
    @ResponseBody
    public String upload(@RequestParam("file") MultipartFile file) throws IOException {
		//如果文件不存在上传失败
        if (file.isEmpty()) {
            LOGGER.info("上传失败");
            System.out.println("文件不存在");
            return "upload fail";
        }
		//获取文件名字
        String fileName = file.getOriginalFilename();
        //设置编译后文件存在路径
        String path = ClassUtils.getDefaultClassLoader().getResource("").getPath()+"static/images/tx/";
        //获取项目路径
        File directory = new File("src/main/resources/static/images/tx");
        String paths = directory.getCanonicalPath();

        File dest = new File(paths+'/' + fileName);
        System.out.println(dest.getAbsoluteFile());

        FileInputStream fileInputStream = (FileInputStream) file.getInputStream();
        //以流的方式上传
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path + File.separator + fileName));
        byte[] bs = new byte[1024];
        int len;
        while ((len = fileInputStream.read(bs)) != -1) {
            bos.write(bs, 0, len);
        }
        bos.flush();
        bos.close();
        try {
        	//文件上传
            file.transferTo(dest);
            LOGGER.info("上传成功");
            return "upload success";
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        return "upload success";
    }

拓展:判断文件上传时文件的类型
https://blog.csdn.net/lpp_dd/article/details/78954297

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值