【图片上传与图片显示】 SpringBoot & ajax (跨域问题)

<上传>

前端:

uploadImg.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!-- 引入bootstrap样式 -->
    <link href="/css/bootstrap.css" rel="stylesheet">
    <!-- 引入bootstrap-table样式 -->
    <link href="/css/bootstrap-table.css" rel="stylesheet">
    <!-- jquery -->
    <script src="/js/jquery.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
    <!-- bootstrap-table.min.js -->
    <script src="/js/bootstrap-table.js"></script>
    <!-- 引入中文语言包 -->
    <script src="/js/bootstrap-table-zh-CN.js"></script>

</head>
<body>
<div class="imageWrapper">
    <div class="row">
        <div class="col-xs-4" style="margin-top: 20px">
            <div>
                <button id="selectImg" type="button" class="btnUpload"></button>
                <input id="imagePic" name="imagePic" type="file"
                       accept=".bmp,.jpg,.png,.jpeg,image/bmp,image/jpg,image/png,image/jpeg" style="display:none" />
            </div>

            <div class="fontTip">
                限上传不超过10M的bmp,jpg,png,jpeg格式的图片
            </div>
            <button id="uploadButton" type="button" onclick="uploadImg();">上传</button>
        </div>
        <div class="col-xs-8">
            <div class="imageShow">
                <img id="uploadImageShow" src="" style="weight:100px;height:100px"/>
            </div>
        </div>
    </div>
</div>
</body>

<script type="text/javascript">
    var btnUploadText = '选择图片';
    $(document).ready(function () {
        $("#selectImg").text(btnUploadText)
        $(".imageShow").hide()
        $('#selectImg').click(function () {
            $('#imagePic').click();
        });
        $("#imagePic").on("change", function (e) {
            var file = e.target.files[0]; //获取图片资源
            var fileTypes = ["bmp", "jpg", "png", "jpeg"];
            var bTypeMatch = false
            for (var i = 0; i < fileTypes.length; i++) {
                var start = file.name.lastIndexOf(".");
                var fileType = file.name.substring(start + 1);
                if (fileType.toLowerCase() == fileTypes[i]) {
                    bTypeMatch = true;
                    break;
                }
            }
            if (bTypeMatch) {
                if (file.size <= 1024 * 1024 * 10) {
                    var reader = new FileReader();
                    reader.readAsDataURL(file); // 读取文件
                    // 渲染文件
                    reader.onload = function (arg) {
                        $(".imageShow").show()
                        $("#uploadImageShow").attr("src", arg.target.result)
                        btnUploadText = '重新上传'
                        $("#selectImg").text(btnUploadText)
                    }
                } else {
                    alert('仅支持不超过10M的图片');
                    emptyImageUpload("#imagePic")
                    $("#uploadImageShow").attr("src", "")
                    $(".imageShow").hide()
                    btnUploadText = '上传'
                    $("#selectImg").text(btnUploadText)
                    return false;
                }
            } else {
                alert('仅限bmp,jpg,png,jpeg图片格式');
                emptyImageUpload("#imagePic")
                $("#uploadImageShow").attr("src", "")
                $(".imageShow").hide()
                btnUploadText = '上传'
                $("#selectImg").text(btnUploadText)
                return false;
            }
        });
    })
    //清空上传图片信息
    function emptyImageUpload(selector) {
        var fi;
        var sourceParent;
        if (selector) {
            fi = $(selector);
            sourceParent = fi.parent();
        } else {
            return;
        }
        $("<form id='tempImgForm'></form>").appendTo(document.body);

        var tempImgForm = $("#tempImgForm");
        tempImgForm.append(fi);
        tempImgForm.get(0).reset();
        sourceParent.append(fi);
        tempImgForm.remove();
    }

    function uploadImg() {
        if($("#imagePic").val() != "") {
            //创建FormData对象
            var formData = new FormData();
            formData.append('photo', document.getElementById('imagePic').files[0]);
            $.ajax({
                type: "POST",
                url:"http://localhost:8080/uploadPhoto",//后台接口
                dataType: "json",
                data:formData,
                fileElementId:"file",  // 文件的id
                async: true, // 使用同步操作
                contentType:false,        /*不可缺*/
                processData: false,         /*不可缺*/
                success: function(data,status,xhr){
                    console.log("返回码:"+data.status+" code:"+data.code+" status:"+status+" xhr:"+xhr.status)
                    if(xhr.status === 200) {
                        alert("上传成功:"+xhr.status+" OK");
                    }
                },
                error: function (d,status,xhr) {
                    console.log("返回码:"+d.status+" code:"+d.code+" status:"+status+" xhr:"+xhr.status)
                    alert("上传失败:"+d.status);
                },
            });
        } else {
            alert("请先选择文件");
        }
    }

</script>
</html>

后端

先在配置文件中设置传输文件的大小(单个文件不得大于10MB,多个文件不能大于100MB)

spring.servlet.multipart.max-file-size = 10MB
spring.servlet.multipart.max-request-size=100MB

MyController.java

package com.example.demo3.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.demo3.dto.MyTableDTO;
import com.example.demo3.entity.User;
import com.example.demo3.service.MyService;
import com.example.demo3.util.HttpHelper;
import com.example.demo3.util.HttpHelperRequestHandler;
import com.alibaba.fastjson.JSON;

import java.io.File;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class MyController {

    @RequestMapping("/")
    @ResponseBody
    public String function0(){
        return "empty";
    }

    /**
     * 图片上传
     * @param photo
     * @param request
     * @return
     */
    @RequestMapping(value = "/uploadPhoto", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> uploadPhoto(MultipartFile photo, HttpServletRequest request,HttpServletResponse response) {
        Map<String, String> ret = new HashMap<String, String>();
        //获取文件后缀
        String suffix = photo.getOriginalFilename().substring(photo.getOriginalFilename().lastIndexOf(".") + 1, photo.getOriginalFilename().length());
        if (!"jpg,jpeg,bmp,png".toUpperCase().contains(suffix.toUpperCase())) {
            ret.put("type", "error");
            ret.put("msg", "请选择jpg,jpeg,bmp,png格式的图片!");
            return ret;
        }

        //存储目录
        String savePath = "E:/imagesFile";   

        File savePathFile = new File(savePath);
        if (!savePathFile.exists()) {
            //若不存在该目录,则创建目录
            System.out.println("若不存在该目录,则创建目录");
            savePathFile.mkdir();
        }
        String filename = new Date().getTime() + "." + suffix;
        try {
            //将文件保存指定目录
            photo.transferTo(new File(savePath + "//"+ filename));
        } catch (Exception e) {
            ret.put("type", "error");
            ret.put("msg", "保存文件异常!");
            e.printStackTrace();
            System.out.println("保存文件异常!");
            return ret;
        }
        ret.put("type", "success");
        ret.put("msg", "上传图片成功!");
        ret.put("filepath", savePath);
        ret.put("filename", filename);

        System.out.println("保存文件成功:"+filename);
        response.setHeader("Access-Control-Allow-Origin", "*");

        return ret;
    }
}

如果为了方便前端访问图片资源的话,可以改变存储路径为项目里的路径

        //存储目录
        String savePath = "E:/imagesFile";   

改为

        //存储目录
        String savePath = getUrl()+"/img/";   //C:/IDEA_Project/Pro_MyBatis3/target/classes/static/img/
public static  String  getUrl() {

        String path = null;
        try {
            String serverPath= ResourceUtils.getURL("classpath:static").getPath().replace("%20"," ");
            path=serverPath.substring(1);//从路径字符串中取出工程路径
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return path;
}

"E:/a.txt" 与 "E:\\a.txt" 都是正确的写法。
为什么反斜杠要两个而正斜杠只要一个:反斜杠中第一个充当转义字符。

由于 / 在不同系统环境中都可以生效,所以最好使用这个

https://blog.csdn.net/piano_diano/article/details/106363592

然后前端的html文件可以在<img>内填入url,即可获得静态图片资源

      <div>
         <img id="uploadImageShow2" src="http://localhost:8080/img/blueSky.jpg" style="weight:100px;height:100px"/>
      </div>

跨域问题

跨域问题来源于JavaScript的"同源策略",即只有 协议+主机名+端口号 (如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题。

解决:

方案1:

在后端代码中加入

response.setHeader("Access-Control-Allow-Origin", "*");

方案2:

给 Controller 实现接口 WebMvcConfigurer,重写addCorsMappings()

@Controller
public class MyController implements WebMvcConfigurer{

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/*").allowedOrigins("*");
    }

}

方案3:

在方法上添加注解 @CrossOrigin

    @CrossOrigin
    @RequestMapping("/table/all")
    @ResponseBody
    public List<MyTableDTO> tableFindAll(){
        return myService.TableFindAll();
}

方案4:

添加配置类

import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author Peko
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");   //允许任何域名使用
        corsConfiguration.addAllowedHeader("*");   //允许任何头
        corsConfiguration.addAllowedMethod("*");   //允许任何方法(post、get等)
        source.registerCorsConfiguration("/**",corsConfiguration);  //处理所有请求的跨域配置
        return new CorsFilter(source);
    }
}

</上传>

<显示>

前端

    <div>
        <img src="http://localhost:8080/downloadPhoto/drrr.jpg">
    </div>

后端

@Controller
public class MyController implements WebMvcConfigurer{

    //解决跨域问题
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("*");
    }
    
    @ResponseBody
    @RequestMapping(value = "/downloadPhoto/{fileN}")
    public String downloadPhoto(@PathVariable String fileN,HttpServletRequest request,HttpServletResponse response) throws IOException {
        String fileName = fileN;
        if(fileName!=null){
            String filePath = "E:/imagesFile/" + fileName;
            System.out.println(filePath);
            File file = new File(filePath);
            if(file.exists()){
                response.setContentType("application/force-download");
                response.addHeader("Content-Disposition","attachment;fileName="+fileName);
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try{
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while(i!=-1){
                        os.write(buffer,0,i);
                        i=bis.read(buffer);
                    }
                    return "download success";
                }catch(Exception e){
                    e.printStackTrace();
                }finally{
                    bis.close();
                    fis.close();
                }
            }
        }
        return "failure";
    }

}

</显示>

参考博文:

https://www.cnblogs.com/yxmhl/p/11617497.html

https://www.cnblogs.com/lguow/p/9603626.html

http://blog.csdn.net/qq_41700374/article/details/87817197

https://www.cnblogs.com/haha12/p/10564972.html

http://baijiahao.baidu.com/s?id=1654419465068708673&wfr=spider&for=pc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值