欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何一步步实现异步上传图片并预览图片(异步加载图片)

程序员文章站 2024-03-24 15:44:10
...

写在开头
最近在做一个美食博客的网站系统,还没有完工,在制作发布文章页面的时候(类似CSDN的Markdown写文章的功能),碰到了需要上传文章图片的的需求,实不相瞒,耗了不少脑细胞!!

准备:文件上传功能

  文件上传功能的实现网上和CSDN有很多的教程,我在这里就简单写一下了哈,如果有不了解的朋友,可以看我的之前学习SSM时候的一篇笔记 “SpringMVC中的文件和上传”
我在实现上传图片的时候就使用以下Controller接口,

package com.chif.controller;
 
import com.alibaba.druid.support.json.JSONUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
import javax.servlet.http.HttpServletRequest;
import java.io.*;
 
@Controller
public class FileController {
    //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
    //批量上传CommonsMultipartFile则为数组即可
    @RequestMapping("/upload")
    @ResponseBody
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
 
        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();
 
        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);
 
        //上传路径保存设置                              !!!!!!!!!!!!!!!!!!!!!!!!!
        String path = request.getServletContext().getRealPath("/img/blog-img");
        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);
 
        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
 
        //读取写出
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return JSONUtils.toJSONString("上传文件成功!");
    }
}

在使用这个Controller实现文件上传的时候只需要更改以下的路径

 String path = request.getServletContext().getRealPath("/img/blog-img");

进入正题!

上传按钮样式实在是太丑了,所以经过我精挑细选,最后决定盗用CSDN中上传头像的样式,哈哈????

原来的:
如何一步步实现异步上传图片并预览图片(异步加载图片)

CSDN的:
如何一步步实现异步上传图片并预览图片(异步加载图片)

我的:
如何一步步实现异步上传图片并预览图片(异步加载图片)
美化按钮的步骤:

  1. 隐藏原来的按钮display: none;
  2. 用div代替按钮,给div添加样式如下
  3. 使用Jquery,让div点击时触发上传文件按钮的点击事件

按钮代码奉上:

       <form action="/upload" enctype="multipart/form-data" method="post" id="upload_img">
           <div class="row" style="height: auto;width: 94%;margin-left: 10px;cursor: pointer;border:1px gainsboro solid;border-radius: 10px 10px;" id="upload_div">
               <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAEbUlEQVR4Xu2aTWgdVRTHz5l8LfyiipKlLnSnC9G4MQYrCIIUdSGVWjCmyTkTMbS6EJFCFqULwQ/CwzcnL1aN1UUofi3cqKWmIFJEEDeCIt1WF2mpEIKZd+TKPHkZ33tzZ+7MvD7e3E3g3Tvnnv/vnnPmzr1BGPKGQ64fKgBVBAw5gSoFhjwAqiLYtxQQkUcB4AgAhKp6ipm/6kc09gWAiBwFgLdigo8R0dtlQygdQBfxLd2lQygVQIL4vkAoDYCl+BaERSKql5EOpQAQER8A3kkpqBQIhQPIKL60SCgUgKP4UiAUBiAn8f9CQMS5hYWFUylTyGp4IQB6iVfVLUT8DQDub/dQVS8AwJ2IuK+D54qIR4qAkDuA1dXV51X13U74I/EzqvoKIh6KjTkNAK+r6rdlQsgVQCR+zURtHEBLPBH9HATB6U4AiOiwiNxdJoTcANiKN2B6ATD9BgIAnAeAmzqlQ7PZPOz7/kdWSZ4wKBcAvcQDwBUAmDYr3/IlCUAE4V4AOFs0BGcA9Xr9kOd5H3YK+0j8fiL6sX0hbACUBcEJQBbxNinQDktECo2EzACyik8LwCYSVPVpZj6TpSZkAuAiPgsACwjmUOVgFgipAbiKzwqgKAipAIjIEwDwSZqC1yksbYtgp2cTaoKJhAPM/KVtOlgDWF5e9iYnJ8029sYOxs2r7n/VvpsTLgCSIkFVLzLzHbkDWF9fv257e/svV/EuKRB/O0Q7xuvjPo2Pj++bnZ29bAPBOgIixzcRcbrNcKqVT7MRsnFeRB5Q1a8R8T8IqvorM99l87wZkwpAvV6/3fO8GgA8pKrfI+LL7Ts820ldU6B9nkajcU8Yhm8i4hQAbIZhuLS4uPi7rS+pANgaTRqXJ4CkuZL6KwBJhIroryKgx3lAEcB72axSoGziee0D8vK7ioC8SKaxUxXBqgh2PxVOE0l5jLWqAWtrazfv7u4eRMQ/d3Z2vlhaWtpxmVxEzC3PbLsNc5fAzOY/RjK3jY2Nka2tradU9VZVPeP7/h9JxhIB1Gq1W8bGxr4DgNYHxi+jo6NTc3NzV5OMd+sPguAlRHyjvb/ZbD7rctQdfa5/joiPR3avqOoMM//ktA8QEfPx80LMyDwRmQuQTG1lZWViYmLiUwB4LDJQI6IXMxmLHgqC4BlE/Dhm4wMies4VwDkAmImF6wlmPu7isHnWfF2av77vX3S1JSInAOC1mJ/nmPlhJwBBEMTPAIy9k0S0ZzJXAa7PB0FwEhFfjQHYZOY9ixefJ7EGVACqCBjyFBARc0G5p5Co6nlENL9fS+0RAHgwVgPOMrP5vWuzqQHvIWLPV8m1RCEG4H1m3rPhSl0Eo8sQ884exPYkEX3mFAGqiiJyARHvGyQCqvoDEU0hojoBiDYst3me1wCAA4MAwdwNjIyMTM/Pz19K8jexBrQbaDQa+8MwPIaINyQZ7lO/2f/XEfEbIvrbxodUAGwMDtqYCsCgrVje/lYRkDfRQbNXRcCgrVje/g59BPwDxZ9wX+EKb6cAAAAASUVORK5CYII=" alt="" class="col-md-offset-4">
               <span class="vicp-hint">点击上传图片至此处</span>
           </div>
           <input type="file" name="file" id="upload_file" style="display: none;"/>
           <!--<input type="submit" value="upload">-->
       </form>

Jquery代码:

 $("#upload_div").click(function () {//div点击触发inputfile按钮上传文件的功能
			$("#upload_file").click();
 });

下面开始我的ajax骚操作了!!!

  1. 进行异步的时间是在文件上传选中文件之后,
  2. 然后异步提交表单,
  3. 成功之后,用.html()将我精心设计的仿CSDN的按钮用<img>覆盖掉,就实现了异步加载图片!
$("#upload_file").change(function () {//选中文件后,异步上传文件并获取上传文件的地址
   var fromData = new FormData($("#upload_img")[0]);
     /*$("#upload_img").submit();//非异步提交上传文件的表单*/
     $.ajax( {/*异步提交上传文件的表单*/
         url:'/upload',
         data:fromData,
         type:'post',
         //ajax2.0可以不用设置请求头,但是jq帮我们自动设置了,这样的话需要我们自己取消掉
         contentType:false,
         //取消帮我们格式化数据,是什么就是什么
         processData:false,
         success:function(data){
             console.log(data);
             //异步刷新图片
             var imgPath=$("#upload_file").val().split("\\");
             var imgName=imgPath[2];
             imgUrl='/img/blog-img/'+imgName;
             $("#upload_div").html('<img src="'+imgUrl+'" alt="" class="img-responsive img-rounded">\n');
         }
 });

在设计的过程中我遇到的问题及解决方案

  1. 使用AJAX实现文件上传时illegal invocation错误,有大佬给指明了方向!!
  2. 之前是在ajax之后再使用.html()覆盖掉按钮,结果导致文件上传了,但是没有刷新页面,所以读取不出来图片!所以我将覆盖的这个操作在ajax成功的success:function中执行就解决了,

如果有朋友想要页面或者项目的源码,可以联系我随时在线!