最近我遇到一個 GitHub 圖片載入的問題
我習慣把 Blog 使用的一些圖片放在 GitHub Repository,網站直接使用 GitHub Raw URL 顯示圖片
原本一直都正常,但最近在單一 Client 一次讀取比較多圖片時,突然開始出現下面的錯誤
429: Too Many Requests
For more on scraping GitHub and how it may affect your rights,
please review our Terms of Service
最後我的處理方式很簡單,也是 AI 提示我的 就是改走 jsDelivr CDN 不要讓 Client 直接讀取 GitHub Raw
另外 GitHub 在點擊 Raw 或取得圖片網址時,也可能拿到這種格式:
https://github.com/donma/BlogResource/blob/main/2569/264203.png?raw=true
這兩種網址直接丟到瀏覽器都可以正常顯示圖片
所以一開始我也沒有特別處理
但問題就在於,GitHub Raw 可以讀取圖片,不代表適合直接拿來當網站的圖片 CDN
當同一個 Client 在短時間內載入大量圖片時,就有機會直接收到:
429: Too Many Requests,可能最近因為 vibe coding 問一下 AI 好像再 2025 下半年開始陸續出現這問題..
1. 簡單的說就是改寫網址把網址改成
網址格式如下:
https://cdn.jsdelivr.net/gh/{owner}/{repo}@{branch}/{path}
例如原本:
https://raw.githubusercontent.com/donma/BlogResource/refs/heads/main/2569/0331-03-42.jfif
轉換後:
https://cdn.jsdelivr.net/gh/donma/BlogResource@main/2569/0331-03-42.jfif
另一種 GitHub Blob URL:
https://github.com/donma/BlogResource/blob/main/2569/264203.png?raw=true
轉換後:
https://cdn.jsdelivr.net/gh/donma/BlogResource@main/2569/264203.png
其實規則不複雜。
GitHub Raw:
/{owner}/{repo}/refs/heads/{branch}/{path}
GitHub Blob:
/{owner}/{repo}/blob/{branch}/{path}
最後統一轉成:
/{owner}/{repo}@{branch}/{path}
2. 這邊提供一個 C# function ,之後你就可以無腦使用
using System;
using System.Linq;
public static string ToJsDelivrUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
return url;
}
Uri uri;
if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
{
return url;
}
string[] segments = uri.AbsolutePath
.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string owner;
string repository;
string branch;
string filePath;
if (uri.Host.Equals(
"raw.githubusercontent.com",
StringComparison.OrdinalIgnoreCase))
{
if (segments.Length < 4)
{
return url;
}
owner = segments[0];
repository = segments[1];
if (segments.Length >= 6 &&
segments[2].Equals(
"refs",
StringComparison.OrdinalIgnoreCase) &&
segments[3].Equals(
"heads",
StringComparison.OrdinalIgnoreCase))
{
branch = segments[4];
filePath = string.Join("/", segments.Skip(5));
}
else
{
branch = segments[2];
filePath = string.Join("/", segments.Skip(3));
}
}
else if (uri.Host.Equals(
"github.com",
StringComparison.OrdinalIgnoreCase))
{
if (segments.Length < 5 ||
!segments[2].Equals(
"blob",
StringComparison.OrdinalIgnoreCase))
{
return url;
}
owner = segments[0];
repository = segments[1];
branch = segments[3];
filePath = string.Join("/", segments.Skip(4));
}
else
{
return url;
}
if (string.IsNullOrWhiteSpace(filePath))
{
return url;
}
return string.Format(
"https://cdn.jsdelivr.net/gh/{0}/{1}@{2}/{3}",
owner,
repository,
branch,
filePath);
}
記得加入:
using System;
using System.Linq;
這個 function 目前支援:
https://raw.githubusercontent.com/{owner}/{repo}/refs/heads/{branch}/{path}
https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path}
以及:
https://github.com/{owner}/{repo}/blob/{branch}/{path}?raw=true
如果不是 Github 圖片網址,就直接回傳原本的 URL
最後說個結論,其實一值把圖片在 Github 上不一定是好事,但是之前就這樣規畫了
所以這目前是一個快速解決的方法,最好的方式還是自己 own 圖片但是就是得自己扛流量
這次遇到 GitHub Raw 回傳 429: Too Many Requests,才發現原本一直可以正常讀取
不代表這個使用方式就適合網站長期使用,改到 jsdelivr 應該是目前最簡單的解法
紀錄一下,給有需要的人