博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js拖拽上传图片
阅读量:5325 次
发布时间:2019-06-14

本文共 3752 字,大约阅读时间需要 12 分钟。

有时候,在开发中,需要遇到拖拽上传图片的需求,即从磁盘选中一张或多张图片,然后按着鼠标把图片拖动到页面上指定的区域,实现图片的上传。

 需要购买阿里云产品和服务的,点击此链接领取优惠券红包,优惠购买哦,领取后一个月内有效: 

1、后端上传图片的接口

我是之前用vue写一个简单的后台系统的时候,用Java的SpringMVC+MyBatis的框架写了一个简单的后台管理的一些接口,刚好有一个上传用户头像的接口,该接口是把上传后的图片存储在另外一台Tomcat下,这里就直接使用这个接口来上传图片。

/**     * 上传用户头像     * @param request     * @param response     */    @ResponseBody    @RequestMapping(value="uploadSysHeadImg.do", method=RequestMethod.POST)    public void uploadSysHeadImg(HttpServletRequest request,HttpServletResponse response){        JSONObject jo = new JSONObject();        //校验token//        boolean f = tokenService.checkToken(request, response);//        if(!f){ return; }                try {            MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());            MultipartHttpServletRequest Murequest = resolver.resolveMultipart(request);                   Map
files = Murequest.getFileMap();//得到文件map对象 // 实例化一个jersey Client client = new Client(); List
fileNameList = new ArrayList<>(); List
relaPathList = new ArrayList<>(); List
realPathList = new ArrayList<>(); for(MultipartFile pic: files.values()){ String uploadInfo = Upload.upload(client, pic, request, response, uploadHost, headImgPath); if(!"".equals(uploadInfo)){ //如果上传成功 String[] infoList = uploadInfo.split(";"); fileNameList.add(infoList[0]); //文件名 relaPathList.add(infoList[1]); //相对路径 realPathList.add(infoList[2]); //真实路径 }else{ //如果上传失败 fileNameList.add(""); relaPathList.add(""); realPathList.add(""); } } jo.put("success", 1); jo.put("error", null); jo.put("fileNameList", fileNameList); jo.put("relaPathList", relaPathList); jo.put("realPathList", realPathList); }catch (Exception e) { jo.put("success", 0); jo.put("error", "上传失败"); } ResponseUtils.renderJson(response, jo.toString()); }

 

2、前端代码

    
Document
+
将文件拖到此处,即可上传

 

我在这里用的是jquery的ajax请求。

里面用的formData对象来上传图片的,该对象的作用是:

  1、用一些键值对来模拟一系列表单控件,即把form中所有表单元素的name与value组装成一个queryString;

  2、异步上传二进制文件

另外有两个属性的值,我们必须要设置它们的值为false:

  contentType: false, //必须 禁止jQuery设置Content-Type请求头

    processData: false, //必须 禁止jQuery处理发送的数据

 

其中先封装了一个 formData 对象,然后使用 post 方法将文件传给服务器。

这里我们就要先说说在 http 中传输文件的问题。起初http协议中没有上传文件方面的功能,直到rfc1867为http协议添加了这个功能。当然在rfc1867中限定form的method必须为POST, enctype = “multipart/form-data” 以及<input type = "file">

当我们使用表单上传文件时,我们来查看他的Request headers,如下图:

发现在 multipart/form-data 后面有boundary以及一串字符,这是分界符,后面的一堆字符串是随机生成的,目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置。说到这肯定就要说说这分界符有啥作用呢?

因为对于上传文件,我们没有在使用原有的 http 协议,所以 multipart/form-data 请求是基于 http 原有的请求方式 post 而来的.那么来说说这个全新的请求方式与 post 的区别

  1. 请求头的不同,对于上传文件的请求,contentType = multipart/form-data是必须的,而 post 则不是,毕竟 post 又不是只上传文件~。

  2. 请求体不同。这里的不同也就是指前者在发送的每个字段内容之间必须要使用分界符来隔开,比如文件的内容和文本的内容就需要分隔开,不然服务器就没有办法正常的解析文件,而后者 post 当然就没有分界符直接以 name = "value"的形似发送。

而在我的这段JQuery ajax() 方法中,我设置了contentType = false,这不是冲突了吗?这当然没有,因为当我们查看这时的 Request headers,会发现还是有分界符。这是因为当我们在 form 标签中设置了enctype = “multipart/form-data”,这样请求中的 contentType 就会默认为 multipart/form-data (我用的是new formData()对象,它其实就是模拟了一个表单控件,也就是form标签)。而我们在 ajax 中 contentType 设置为 false 是为了避免 JQuery 对其操作,从而失去分界符,而使服务器不能正常解析文件。

 

 3、效果

 

 需要购买阿里云产品和服务的,可以点击此链接领取优惠券红包,优惠购买哦,领取后一个月内有效: 

转载于:https://www.cnblogs.com/libo0125ok/p/11344972.html

你可能感兴趣的文章
Tableau 学习资料
查看>>
中断和异常
查看>>
lucene 全文检索工具的介绍
查看>>
C# MD5-16位加密实例,32位加密实例
查看>>
无线点餐系统初步构思
查看>>
AJAX
查看>>
前端之CSS
查看>>
List注意点【修改】
查看>>
sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
查看>>
拓扑排序的原理及其实现
查看>>
对StageWebView捕获位图时空白
查看>>
Provison Profile管理及存放路径
查看>>
shop--8.店铺列表展示--前端开发
查看>>
转:Can not issue data manipulation statements with executeQuery()错误解决
查看>>
详解C#委托,事件与回调函数(转)
查看>>
744. Find Smallest Letter Greater Than Target
查看>>
Android 发展思路
查看>>
Sharepoint 自定义字段
查看>>
MySQL 触发器简单实例
查看>>
MySQL------报错Access denied for user 'root'@'localhost' (using password:NO)解决方法
查看>>