LOGI

新浪图床防盗链始末

新浪图床加防盗链检测已经是很久以前的事了,那时我还在用静态博客,虽然也中了招,但只有几篇帖子,影响不大。但今天有博友留言仍未解决,希望有办法暂时恢复图片显示,慢慢迁移,所有我就借花仙佛,总结一下已有的快速恢复和迁移方法。

[collapse title="可忽略内容"]

问题发生后,万能网友很快发现,空 referrer 头仍能获取图片,这说明新浪未做强防盗链检测。已有机制是校验 HTTP 协议头的 referrer 字段,即来源验证。具体来说,假如你的帖子 http://blog.xx.com/123.html 引用了一张新浪图片,浏览器向服务器请求该图片时,会把 referrer=http://blog.xx.com/123.html 一并发送过去,新浪检查到非官方来源便返回了 403 禁止访问。如果强制发送 referrer= 或不发送该字段,服务器仍正常返回,所以就有了以下各种 no-referrer 配置。

前端

META

方式一,在每个页面的 head 部分添加 meta 标签,会导致站点评论、统计等功能失效,因为它们同样依赖来源。

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

IMG

方式二,给每张图片单独配置 referrer 策略,不兼容 IE、Edge 和 Safari on iOS。

<img src="demo.jpg" referrerpolicy="no-referrer">

IFRAME

方式三,将图片放到 iframe,每张图片都写这么多代码,没人有耐心,且有相同的兼容性问题。

<script>
    function iframeLoaded(target) {
        var img = target.contentDocument.images[0];
        target.width = img.width;
        target.height = img.height;
    }
    window.sina = '<img src="//wx4.sinaimg.cn/large/007iuyE8gy1g2g8p3ovr3j30t314lhdt.jpg">';
</script>
<iframe 
    referrerpolicy="no-referrer"
    src="javascript:parent.sina"
    scrolling="no"
    frameborder="0"
    onload="iframeLoaded(this)">
</iframe>

后端

Referrer-Policy

方式四,通过 NgnixApache 等 Web 服务器,直接告诉浏览器 Referrer-Policy: no-referrer,效果同方式一,意味着有相同的副作用。

Nginx

add_header Referrer-Policy no-referrer;

Apache

Header always set Referrer-Policy "no-referrer"

反向代理

方式五,反代,让后端构造任意 referrer,如 referrer=https://m.weibo.cn 获取图片,转发给前端,这样前端就无需任何配置,也就不会产生副作用。

可以用自己的 服务器CDNCloudflare 等搭建反代,也可使用如下第三方代理。

<!-- 新浪官方未加验证域名 -->
<img src="//tva1.sinaimg.cn/large/007iuyE8gy1g2g8p3ovr3j30t314lhdt.jpg">

<!-- Wordpress 官方反代 -->
<img src="//i0.wp.com/wx4.sinaimg.cn/large/007iuyE8gy1g2g8p3ovr3j30t314lhdt.jpg">

<!-- 百度图片搜索反代 -->
<img src="//image.baidu.com/search/down?tn=download&url=https://wx4.sinaimg.cn/large/007iuyE8gy1g2g8p3ovr3j30t314lhdt.jpg">

替换链接

有了反代服务器后就要把站点所有新浪图片都替换成反代链接。

服务器替换

可通过 NginxApache 插件实时检查。我没有动力详细介绍,读者可参考 Nginx 内容替换模块 http_substitutions_filter_module 实用案例分享使用 mod_ext_filter 组件在 Apache 中实现输出内容的替换,为所有页面增加统计功能

下面是 ngx_http_substitutions_filter_module 的配置示例,这个模块要自行编译安装。

sub_filter '[0-9a-z]{3}.sinaimg.cn/large/' 'i0.wp.com/wx4.sinaimg.cn/large/' ir;

数据库替换

如果不熟悉 Nginx 编译安装,可以使用数据库替换的方法,Typecho 参考 Typecho 网站域名更换方法,Wordpress 参考 WordPress 迁移站点更换域名为新域名的 N 种方法。注意备份数据库,执行命令时仔细甄别表名,字段名,不可无脑操作。

[/collapse]

浏览器替换

如果以上内容都不熟悉,可直接使用 JS 代码在浏览器替换。对于 本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后)。其他主题,加入到主题对应的 header.php 中的 </head> 标签前。

<script>
    // 临时替换新浪图床为反代链接
    document.addEventListener('DOMContentLoaded', initSinaProxy);
    function initSinaProxy() {
        var sinaImgs = document.querySelectorAll('img[src*="sinaimg.cn"]');
        for (var i = 0; i < sinaImgs.length; i++) {
            var img = sinaImgs[i];
            img.src = '//tva1.sinaimg.cn/large/' + img.src.split('/').pop();
        }
    }
</script>

如果你开启了 PJAX,可能需要单独加入回调函数。对于本主题,依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initSinaProxy(); 添加进入即可。

迁移

前面说了这么多 Linux 操作,还是挺麻烦的,关键是我没有动力详细写,如有困难可留言,我宁愿直接操作服务器。TypechoWordpress 用户可使用链接中的迁移工具简化操作。

最后,今后一定要将所有图片放到自己的 CDN,同时在其他地方按文章名称建立备份文件夹,以防数据丢失。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »