很久以前用 js 给网站写了个站外链接卡片,最近给它加上了 B 站链接的解析。写文章时只需一行代码就可以将 B 站链接自动转化为链接卡片,例如 :[share url="https://www.bilibili.com/video/BV1TM4y1T7sw"] 。
2024/8/07 更新:新主题卡片解析已失效,下面是效果图
卡片效果
为了实现卡片背景的渐变效果,一般是使用 background 属性中的 linear-gradient 样式给背景加上一个背景渐变。一开始,打算通过 B 站 API 获取视频封面图并直接应用于 background,但测试的时候发现 B 站的图床启用了防盗链,导致图片无法直接使用。经过一番尝试,找到了两种解决方案。
曲线救国
防盗链机制通常依赖于资源服务器检查请求的 Referer 头,允许来自指定 Referer 头的请求访问资源。如果 Referer 头指向的是非指定的页面,则会拒绝提供资源,从而导致图片加载失败。
在 HTML 中有一个 referrerpolicy 属性,该属性用于控制当用户点击页面上的链接或发起请求时,是否向目标 URL 发送 Referer 请求头。当 referrerpolicy 取 no-referrer 的时候,浏览器将不会发送 Referer 请求头,资源服务器也无法获取到任何 Referer 信息。 当资源服务器没有设置拒绝空 Referer 访问的时候 ,通过给 <img> 设置 referrerpolicy="no-referrer" 属性即可绕过防盗链机制获取到图片。
Note
<div>标签不支持referrerpolicy="no-referrer"属性。
因为 <img> 标签不支持直接在 style 属性中应用背景渐变,所以最后我们需要额外添加一个渐变遮罩:
<div class="relative w-[500px]">
<img
src="https://i0.hdslb.com/bfs/archive/b73aec2f46bcaddee266b900d714b78f47e726d2.jpg"
alt="Bili Image"
class="w-full h-full object-cover"
referrerpolicy="no-referrer"
/>
<!-- 遮罩 -->
<div
class="absolute top-0 left-0 w-full h-full bg-gradient-to-r from-transparent to-white pointer-events-none"
></div>
</div>
当然,利用浏览器的缓存,我们写成下面这个结构也是能正常实现效果的:
<div
style="
background: linear-gradient(to right, transparent 10%, white),
url(https://i0.hdslb.com/bfs/archive/b73aec2f46bcaddee266b900d714b78f47e726d2.jpg);
"
>
<img
src="https://i0.hdslb.com/bfs/archive/b73aec2f46bcaddee266b900d714b78f47e726d2.jpg"
referrerpolicy="no-referrer"
hidden
/>
</div>
当浏览器加载完成 <img> 标签的图片之后,<div> 标签内的背景会直接从浏览器的缓存里面加载,从而通过 <img> 标签间接解决 div 不支持 referrerpolicy="no-referrer" 属性的缺点。
第三方的图像缓存
另一种方法是通过设置代理来绕过防盗链,可以通过下面这段 PHP 代码实现:
或者通过第三方图像缓存服务,这里用的是 https://images.weserv.nl 这个网站的服务。只需在 https://images.weserv.nl/?url= 后加上目标图片的 URL,就可以绕过防盗链了。
Warning最后还是要提一句,不要上传有敏感数据的图片到第三方网站,也不要滥用他们的服务,毕竟谁也不想用着用着就没有了。
