博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
防盗链与springboot代理模式(图片文件转发)
阅读量:6697 次
发布时间:2019-06-25

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

在搭建自己的博客网站的时候,很有可能要引入一些外部图片,毕竟多数人最开始不是在自己的平台上写博客。  因某种需要,搬运自己以前写的博客到自己的网站时,在图片这一步可能会出现问题,无法显示。其中往往就是防盗链在起作用了

防盗链

定义

百度百科给的解释是

此内容不在自己服务器上,而通过技术手段,绕过别人放广告有利益的最终页,直接在自己的有广告有利益的页面上向最终用户提供此内容。 常常是一些名不见经传的小网站来盗取一些有实力的大网站的地址(比如一些音乐、图片、软件的下载地址)然后放置在自己的网站中,通过这种方法盗取大网站的空间和流量。

可能有点不易懂,通俗的讲,就是 出于某些原因(服务器或图片来源等),从别的网站引入图片到自己的网站中。这样连服务器的存储空间费用都省了( •̀ ω •́ )✧

原理

防盗链实现的原理就是:http协议中有个叫referer的表头字段,采用URL的格式来表示从哪儿链接到当前的网页或文件。换句话说,通过referer,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址。有了referer跟踪来源,就可以通过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面。比如防盗链通常返回的403 forbidden。

实现

apache 服务器通常使用它的 Url Rewrite功能来实现

具体可参考

反防盗链

任何事物都有相对的两面,既然有了防盗链,那么肯定也有反防盗链。

下载文件

将目标文件下载到自己的服务器,然后从本地读取,这个方法应该算是比较憨厚的一种了。不过准确说这个也不算啥反防盗链

使用代理模式

就是下面详细讲的代理模式

文件代理模式

由于防盗链的关键在于referer头部, 而浏览器获取图片时,它会老实的填上真是来源。比如从某个博客访问,就填上博客地址。不过我们手动访问图片地址时,是不带referer的,这时就可以访问。因此,我们可以实现一个代理模式,来转发图片。

比如有防盗链的图片地址 www.aa.com, 服务器地址 www.bb.com, 先让服务器来请求(不带referer)得到图片,再将请求到的图片转发给目标网站(比如个人博客网站)。也就是博客上的图片src直接填

www.bb.com/forward?url=www.aa.com

当然我们要在服务器上实现相应的图片转发功能。

下面将以springboot 为例,实现图片转发:


首先设置相应接口

@RequestMapping(value = "/forward")    public ResponseEntity
forward(@RequestParam(name = "url", required = true) String url){ System.out.println("Start: ------------------------->"); Resource resource = null; InputStream inputStream; try { inputStream = new URL(url).openStream(); resource = new ByteArrayResource(toByteArray(inputStream)); } catch (Exception e) { e.printStackTrace(); } return ResponseEntity.ok() .contentType(MediaType.IMAGE_PNG) .header(HttpHeaders.CONTENT_DISPOSITION, " filename=\"" + getFileName(url) + "\"") .body(resource); }

加上ResponseEntity是为了更好的控制Response,比如响应的头部信息等。

其中的toByteArray()函数为

private byte[] toByteArray(InputStream in){        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();        try {            byte[] bytes = new byte[1024];            int n;            while ((n = in.read(bytes)) != -1){                byteArrayOutputStream.write(bytes, 0, n);            }            System.out.println(byteArrayOutputStream.size());        } catch (Exception e) {            e.printStackTrace();        }        return byteArrayOutputStream.toByteArray();    }

getFileName()函数为

private String getFileName(String url){        String[] strs = url.split("/");        for (String str: strs){            // 这里我仅处理png格式的,根据需求修改即可            if (str.toLowerCase().endsWith(".png")){                return str;            }        }        return null;    }

最后

就以cnblog上一图片 https://img2018.cnblogs.com/blog/1470456/201812/1470456-20181206174653015-309070173.png 举个例子

如图,转发成功(~ ̄▽ ̄)~

1470456-20190101203847567-181089394.png

转载于:https://www.cnblogs.com/asche/p/10205745.html

你可能感兴趣的文章
python 列表模拟堆栰
查看>>
Linux-Centos5.3中文乱码问题解决
查看>>
linux分区学习[ CentOS ]
查看>>
aaa认证
查看>>
廖雪峰官网学习js 字符串
查看>>
phpcms 如何获取文章
查看>>
C#匿名类型
查看>>
ActiveMQ
查看>>
Nginx服务器部署 负载均衡 反向代理
查看>>
C++学习笔记:指向函数的指针
查看>>
# 2017-2018-1 20155319 实验五 《通讯协议设计》
查看>>
通用后台管理系统(1)-数据库设计
查看>>
做自适应网页
查看>>
ACM的奇计淫巧_bitset优化
查看>>
centos 配置防火墙操作
查看>>
比亚迪速锐F3专用夏季座套 夏天坐垫 四季坐套
查看>>
Java web 实现 之 Filter分析ip统计网站的访问次数
查看>>
bzoj1303
查看>>
2015.3.12 C#运用正则表达式点滴
查看>>
CSS布局自适应等分比例
查看>>