昔、JavaScriptでサイト外リンクカードを作り、最近Bilibiliリンクの解析を追加した。記事を書く際は一行のコードでBilibiliリンクを自動的にカードに変換できる。例:[share url="https://www.bilibili.com/video/BV1TM4y1T7sw"]。
2024/8/07 更新:新テーマカード解析は既に無効。以下は効果図
カード効果
カード背景のグラデーション効果を実現するには、通常backgroundプロパティのlinear-gradientスタイルで背景グラデーションを追加する。最初はBilibili APIから動画サムネイルを取得してbackgroundに直接適用しようとしたが、テスト中にBilibiliの画像サーバーが盗難防止を有効にしており画像が直接使用できないことが判明。いろいろ試した結果、2つの解決策を見つけた。
遠回り策
盗難防止メカニズムは通常、リソースサーバーがリクエストの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最後に注意:機密データを含む画像をサードパーティサイトにアップロードしないでください。また、サービスを乱用しないでください。いつか使えなくなるかもしれません。
