解决微信公众号复制至网站时“此图片来自微信公众平台 未经允许不可引用”问题

未标题-2.jpg

原因:

微信启用了防盗链功能,禁止其他网站直接调用微信的图片。防盗链的原理主要是外部网站访问资源时,默认会带有HTTP请求的Referer头部,服务端就可以通过这个HTTP请求的Referer头部,来判断来源地址是否存在于引用白名单里面,如果在白名单,就显示正常的图片,如果不在,就返回防盗链图片。


解决思路:

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

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

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


解决方案:

  • 1、在网页的<head></head>定义该页面不发送任何Referer头信息,添加代码<meta name="referrer" content="no-referrer">

  • 2、在图片img标签加入 referrerpolicy="no-referrer" 属性,意思是该图片的引用的时候,不发送Referer头信息(该方式IE不支持),我们通过JS代码实现,代码如下。

<script>
    $(document).ready(function(){
        //给文章内容区域的img标签增加 referrerpolicy="no-referrer" 参数,实现不发送Referer头部,达到绕过防盗链的效果
        $('.article .article-body 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());
            }
        });
    });
</script>