排查并解决把微信公众号的文章复制到网站的时候,出现“此图片来自微信公众平台 未经允许不可引用”问题

浏览数(1069)

排查并解决把微信公众号的文章复制到网站的时候,出现“此图片来自微信公众平台 未经允许不可引用”问题

0

前几天,把微信公众号上的内容复制到网站的时候,一开始还好好的,发布到线上服务器的时候,出现了文章里面的图片全部被替换成了“此图片来自微信公众平台 未经允许不可引用”的图片,根据过往经验,是腾讯使用了防盗链的机制

640.jpg

一、网站为什么会使用防盗链,防盗链的原理是什么?

网站做防盗链主要是为了防止网站的图片,视频等静态资源被第三方网站引用,给服务器造成不必要的资源(内存,CPU)和带宽(网速,流量)消耗

防盗链的原理主要是使用img等标签引用外部图片的时候,通常默认会带有HTTP请求的Referer头部,服务端就可以通过这个HTTP请求的Referer头部,来判断来源地址是否存在于引用白名单里面,如果在白名单,就显示正常的图片,如果不在,就返回防盗链图片


二、如何解决这个问题?

解决这个问题,一般有三种方案

①、通过网站的编辑器(前端JavaScript)判断复制过来的文章是否存在外链图片,如果存在,就提交给后端(如php或者Java之类的)把这张图片下载到服务器,并改变图片路径为本地服务器路径(如果外链图片过多或者过大,容易造成本地服务器资源和带宽的消耗)。

②、在引用该外链图片的时候,通过网站的后端去访问这张图片的URL,然后通过服务器中转,并呈现目标图片给用户前端访问(如果外链图片过多或者过大,容易造成本地服务器资源和带宽的消耗,且如果通过服务器访问外链图片次数过多,容易被对方的网站管理员发现并封ip

③、前面说过,目标服务器是通过img等标签请求的时候,默认带的Referer头部参数来判断是否外链访问,那么,前端访问这张图片的时候,把默认的Referer头部去掉,就可以实现绕过防盗链的效果了。


三、如何去掉默认的Referer头部?

一般有两种方案:

①、在文章页面的头部加入以下这行代码,大概意思是全局定义该页面不发送任何Referer头信息(这个方式是有效的,但我不想要全局定义)。

<meta name="referrer" content="no-referrer">

②、在图片img标签加入 referrerpolicy="no-referrer" 属性,大概意思是该图片的引用的时候,不发送Referer头信息(目前来看,只有ie浏览器不支持这种方式,其他浏览器都支持,不过我也没有想过要兼容ie)。


因为网站的编辑器默认是不会给图片加入 referrerpolicy="no-referrer" 参数的,所以需要通过前端(JavaScript)来处理,我目前是用jQuery来处理这个效果。

$(document).ready(function(){
    //给文章内容区域的img标签增加 referrerpolicy="no-referrer" 参数,实现不发送Referer头部,达到绕过防盗链的效果
    $('.main section .articletext img').attr('referrerpolicy', 'no-referrer');
});

后面发现,参数是加入进来了,但是图片没有变化,主要原因是图片参数是在网站图片加载完成过后,再通过JavaScript增加的,所以没有重新获取图片,要解决这个问题,可以给图片的路径增加随机参数,达到重新获取图片的效果。

$(document).ready(function(){
    //给文章内容区域的img标签增加 referrerpolicy="no-referrer" 参数,实现不发送Referer头部,达到绕过防盗链的效果
    $('.main section .articletext img').each(function(){
        //设置referrerpolicy属性
        $(this).attr('referrerpolicy', 'no-referrer');
        //获取原始src
        var originalSrc = $(this).attr('src');
        //在src后添加随机数强制重新加载
        $(this).attr('src', originalSrc + '?' + new Date().getTime());
    });
});

到这里,图片加载的问题解决了,但是又出现了新的问题,因为网站的文章图片,并不全是微信公众号的外链图片,如果所有的图片都加载两次(先默认加载,然后增加了 referrerpolicy="no-referrer" 参数再加载一次),就会增加服务器的资源和带宽消耗,所以,我只需要微信公众号过来的图片进行参数处理,其他的不变就可以了。

$(document).ready(function(){
    //给文章内容区域的img标签增加 referrerpolicy="no-referrer" 参数,实现不发送Referer头部,达到绕过防盗链的效果
    $('.main section .articletext img').each(function(){
        //先判断是不是来自于微信公众号的图片服务器的域名,如果是就增加参数并更新图片,如果不是就维持现状
        var imgSrc = $(this).attr('src');
        var url = new URL(imgSrc);
        if (url.hostname === 'mmbiz.qpic.cn') {
            $(this).attr('referrerpolicy', 'no-referrer');
            $(this).attr('src', imgSrc + '?' + new Date().getTime());
        }
    });
});

自此,问题解决。

注:本文由www.lcsay.com发表,如需转载或已侵权,请联系我。

✎﹏𝓁𝒸𝓈𝒶𝓎﹍﹍·

评论0