前端下载其他服务器上的跨域图片资源问题

问题描述

       项目中有一个需求,需要从客户端(网页)批量下载服务器存储的图片到本地,但是服务器只存储了图片url地址,图片本身存在于别的服务器上,当我们请求图片的时候,会出现跨域问题,尽管前端解决了跨域,但是还需要服务器允许跨域请求资源,因为有多个服务器所以从服务器端解决不太理想。

解决思路

       首先,可以通过后台JAVA方法,把别的服务器上的图片下载到项目服务器(后台请求没有跨域的问题),下载到本地之后,在通过前端轮子从项目服务器下载就不会跨域了。

一. 后台下载

 public EiInfo ExportPhoto(EiInfo inInfo) {
    EiInfo outInfo = new EiInfo();
    HashMap map=new HashMap();
    //从前端获取查询条件
    map.put("number",inInfo.getBlock("inqu_status").getRow(0).get("number"));   
    map.put("jgsjStart",inInfo.getBlock("inqu_status").getRow(0).get("jgsjStart"));
    map.put("jgsjEnd",inInfo.getBlock("inqu_status").getRow(0).get("jgsjEnd"));
    map.put("deviceaddress",inInfo.getBlock("inqu_status").getRow(0).get("deviceaddress"));
    map.put("csys",inInfo.getBlock("inqu_status").getRow(0).get("csys"));
    map.put("hpys",inInfo.getBlock("inqu_status").getRow(0).get("hpys"));
    map.put("cerType",inInfo.getBlock("inqu_status").getRow(0).get("cerType"));
    map.put("fxbh",inInfo.getBlock("inqu_status").getRow(0).get("fxbh"));


	//获取需要导出的数据集
    List<HashMap> list = dao.query( "BMGS02.queryJgclPhoto", map);

    List result = list;
    int num=0;
    ArrayList arrayList = new ArrayList();
    //遍历数据集,获取每条数据的图片地址 
    for(int i=0;i<result.size();i++){
        BM05 bm05  = new BM05();
        bm05.fromMap((Map) result.get(i));
        int i1 = bm05.getTpurl().lastIndexOf("/");   //因为图片地址很长,我们需要找到图片名称并截取出来,图片下载到服务器上之后重新拼接上服务器IP形成新的地址
        String substring = bm05.getTpurl().substring(i1+1, bm05.getTpurl().length()); 
        arrayList.add(substring);
        
		//调用根据url下载图片的方法,需要传下载的url,下载路径(建议在项目所在文件夹创建文件,因为浏览器保护没办法直接访问到项目服务器的本地文件,但是我们可以访问项目文件),图片名称
        boolean b = httpDownload("图片地址", "图片下载地址" + substring);  

        if(b){
            num+=1;
        }
    }
    outInfo.set("photoList",arrayList);

    return outInfo;
}
public static boolean httpDownload(String httpUrl, String saveFile) {
    // 1.下载网络文件
    int byteRead;
    URL url;
    try {
        url = new URL(httpUrl);
    } catch (MalformedURLException e1) {
        e1.printStackTrace();
        return false;
    }

    try {
        //2.获取链接
        URLConnection conn = url.openConnection();
        //3.输入流
        InputStream inStream;
        inStream = conn.getInputStream();
        //3.写入文件   
        FileOutputStream fs = new FileOutputStream(saveFile);

        byte[] buffer = new byte[1024];
        while ((byteRead = inStream.read(buffer)) != -1) {
            fs.write(buffer, 0, byteRead);
        }
        inStream.close();
        fs.close();
        return true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

//删除指定文件夹下的所有文件,避免下载图片过多导致服务器内存不足
public EiInfo deletePhoto(EiInfo inInfo) {
    delAllFile(文件路径); 

            return  inInfo;
}
public static boolean delAllFile(String path){

    boolean flag = false;

    File file = new File(path);

    if(!file.exists()){

        return flag;

    }

    if (!file.isDirectory()) {

        return  flag;

    }

    String[] tempList = file.list();

    File temp = null;

    for (int i = 0; i < tempList.length; i++) {

        if (path.endsWith(File.separator)) {

            temp = new File(path  + tempList[i]);

        } else {

            temp = new File(path + File.separator + tempList[i]);

        }

        if (temp.isFile()) {

            temp.delete();

        }

        if (temp.isDirectory()) {

            delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件

//                delFolder(path + "/" + tempList[i]);//再删除空文件夹

            flag = true;

        }

    }

    return flag;

}

二.前端下载

//引入需要的js
<script src="../static/js/jszip.js"></script>
<script src="../static/js/FileSaver.js"></script>

//先从服务器上下载图片 然后清除服务器上缓存下来的图片
      var photoList=eiInfo.get("photoList");  //获取服务器上新的图片地址列表
      var photoArr=[];
      for(var i=0;i<photoList.length;i++){ //遍历图片列表
      	  //根据图片名称 拼接图片对象
          photoArr.push({url:"http://localhost:8080/rc/static/downPhoto/"+photoList[i],name:photoList[i]}) 
      }
      //调用批量下载图片的方法
       FunLib.download(photoArr);

	//   下载图片
var FunLib = {     //该方法需要服务器支持跨域 或者从跨域的服务器上获取图片到本地服务器
    // 图片打包下载
    download: function (images) {
        FunLib.packageImages(images)
    },
    // 打包压缩图片
    packageImages: function (imgs) {
        var imgBase64 = []
        var imageSuffix = [] // 图片后缀
        var zip = new JSZip()
        var img = zip.folder("images")

        for (var i = 0; i < imgs.length; i++) {
            var src = imgs[i].url
            var suffix = src.substring(src.lastIndexOf("."))
            imageSuffix.push(suffix)
            FunLib.getBase64(imgs[i].url).then(function (base64) {
                imgBase64.push(base64.substring(22))
                if (imgs.length === imgBase64.length) {
                    for (var i = 0; i < imgs.length; i++) {
                        img.file(imgs[i].name + imageSuffix[i], imgBase64[i], {base64: true})
                    }
                    zip.generateAsync({type: "blob"}).then(function (content) {
                        saveAs(content, "images.zip")
                        downPhoto=true;
                    })
                }
            }, function (err) {
                console.log(err)
            })
        }
    },
    // 传入图片路径,返回base64
    getBase64: function (img) {
        var image = new Image()
        image.src = img+'?time=' + new Date().valueOf();
        image.crossOrigin = '*';
        var deferred = $.Deferred()
        if (img) {
            image.onload = function () {
                var canvas = document.createElement("canvas")
                canvas.width = image.width
                canvas.height = image.height
                var ctx = canvas.getContext("2d")
                ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
                var dataURL = canvas.toDataURL()
                deferred.resolve(dataURL)
            }
            return deferred.promise()
        }
    }
}

三.过程中的坑
1.跨域不仅需要前端解决,还需要资源服务器允许跨域
2.图片下载到项目服务器时,如果下载到本地目录里,那么前端无法通过ip:8080路径访问到图片。所以需要在项目文件夹里新建文件存放图片。
3.tomcat文件新增图片资源的时候 需要加载图片,不然虽然可以在文件里看到图片,但是再打开的项目上无法访问到图片。把文件建在构建好的文件里,就不会出现tomcat需要时间加载的问题了。
4.下载完图片记得删除,不然可能占太多服务器内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值