Skip to content

Commit e484a48

Browse files
committed
fix: serve cdn.tw93.fun images via cloudflare image transforms
Blog media migrated from cdn.fliggy.com to Cloudflare R2 (cdn.tw93.fun), but R2 ignores Aliyun's ?x-oss-process= params, so those images were silently served as full-size originals (a 2.4MB jpeg stayed 2.4MB). Route cdn.tw93.fun through Cloudflare /cdn-cgi/image/ transformations (auto webp/avif, w2000, q80, scale-down) and keep x-oss-process only for the still-live Aliyun CDNs.
1 parent 42d6aff commit e484a48

1 file changed

Lines changed: 28 additions & 4 deletions

File tree

rehype-image.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,32 @@ function getImageMetadata() {
2424
}
2525
}
2626

27+
// Build an optimized image URL based on the source host:
28+
// - cdn.tw93.fun (Cloudflare R2): wrap with /cdn-cgi/image/ transformation (auto webp/avif).
29+
// R2 does NOT support Aliyun's ?x-oss-process= params, so they must not be used here.
30+
// - live Aliyun OSS CDNs: keep appending ?x-oss-process= params (still valid on those hosts).
31+
// - github raw / camo / anything else: no URL-based optimization available, return unchanged.
32+
const CF_DOMAIN = "cdn.tw93.fun";
33+
const CF_TRANSFORM = "width=2000,quality=80,format=auto,fit=scale-down";
34+
const OSS_DOMAIN_REGEX =
35+
/^https:\/\/(?:cdn\.alipayobjects\.com|gw\.alipayobjects\.com|gw\.alicdn\.com|img\.alicdn\.com)\//;
36+
const OSS_PROCESS =
37+
"x-oss-process=image/auto-orient,1/resize,w_2000/format,webp";
38+
39+
function optimizeImageUrl(url) {
40+
const cfPrefix = `https://${CF_DOMAIN}/`;
41+
if (url.startsWith(cfPrefix)) {
42+
if (url.includes("/cdn-cgi/image/")) return url;
43+
return `${cfPrefix}cdn-cgi/image/${CF_TRANSFORM}/${url.slice(cfPrefix.length)}`;
44+
}
45+
if (OSS_DOMAIN_REGEX.test(url)) {
46+
if (url.includes("x-oss-process")) return url;
47+
const separator = url.includes("?") ? "&" : "?";
48+
return `${url}${separator}${OSS_PROCESS}`;
49+
}
50+
return url;
51+
}
52+
2753
const getHeroImage = (tree) => {
2854
let heroUrl = null;
2955
visit(tree, "raw", (node) => {
@@ -35,8 +61,7 @@ const getHeroImage = (tree) => {
3561
/https:\/\/(?:cdn\.(?:fliggy\.com|alipayobjects\.com)|gw\.(?:alipayobjects\.com|alicdn\.com)|img\.alicdn\.com|raw\.githubusercontent\.com|camo\.githubusercontent\.com|cdn\.tw93\.fun)/;
3662
const skipRegex = /\.(?:gif|svg|GIF|SVG)(?:\?.*)?$/;
3763
if (url.match(domainRegex) && !url.match(skipRegex)) {
38-
const separator = url.includes("?") ? "&" : "?";
39-
heroUrl = `${url}${separator}x-oss-process=image/auto-orient,1/resize,w_2000/format,webp`;
64+
heroUrl = optimizeImageUrl(url);
4065
}
4166
}
4267
});
@@ -81,7 +106,6 @@ export default function rehypeCustomizeImageSrc() {
81106

82107
imageIndex++;
83108
const isFirstImage = imageIndex === 1;
84-
const separator = p1.includes("?") ? "&" : "?";
85109
const meta = imageMetadata[p1];
86110

87111
// Extract original width/height if they exist
@@ -94,7 +118,7 @@ export default function rehypeCustomizeImageSrc() {
94118
? originalHeightMatch[1].replace("px", "")
95119
: null;
96120

97-
let newAttrs = `src="${p1}${separator}x-oss-process=image/auto-orient,1/resize,w_2000/format,webp" data-lightense-src="${p1}" data-pswp-src="${p1}"`;
121+
let newAttrs = `src="${optimizeImageUrl(p1)}" data-lightense-src="${p1}" data-pswp-src="${p1}"`;
98122

99123
// Use metadata for aspect-ratio and lightbox, user-specified for display size
100124
const metaWidth = meta?.width;

0 commit comments

Comments
 (0)