使用 Cloudflare Images 转换 + Workers 实现托管在 CF 的图床无感压缩
最近发现了 Cloudflare 有一个 Images 转换服务,可以用来处理图片,搭配 Workers,实现访问图片的 URL 不变,无感压缩图片,很适合图床使用。当然前提是图片托管到 CF,小黄云代理或是 R2 对象存储都可以。免费版每月有 5000 次的转换额度,实际上一张图片转换过一次后就会缓存,下次访问不会再占额度。另外,只对嵌入在网页中的图片有效,不影响单独标签页打开图片。
实现效果
以香港-深圳-广州游为例,7-8MB 的 JPG 原图被压缩为了 1-2MB 的 WEBP 图片,大幅缩短了打开网站所需的时间,部分图片压缩时间超过免费版 Workers 限制,保持原图。

配置步骤
接下来的教程中提及到的域名如下,请自行替换为你的域名:
example.com
:域名www.example.com
:图床域名
第一步:启用 Cloudflare Images 转换
首先来到 Dashboard,找到 Images -> 转换,给 example.com
启用转换。

第二步:配置源服务器
然后在源里面添加指定源服务器:www.example.com
,保存。

第三步:创建 Workers
来到 Workers,创建一个 Worker,填入以下代码:
export default {
async fetch(request) {
if (/image-resizing/.test(request.headers.get("via"))) {
return fetch(request)
}
let options = { cf: { image: {} } };
const accept = request.headers.get("Accept");
if (/image\/webp/.test(accept)) {
options.cf.image.format = "webp";
} else if (/image\/avif/.test(accept)) {
options.cf.image.format = "avif";
}
const imageRequest = new Request(request.url, {
headers: request.headers,
});
let transformRequests = fetch(imageRequest, options);
if ((await transformRequests).status == 200) {
return transformRequests;
} else {
return fetch(request);
}
}
};
这段代码会处理来自用户的请求,然后发起转换请求。免费的 Workers 只有 10ms 的 CPU 时间,所有是有概率转换失败的,这时候会绕过转换直接请求图床。
第四步:配置 Workers 路由
最后来到设置配置 Workers 路由,填入 www.example.com/*
,这样写的话需要确保该整个 www.example.com
上只有图片,否则对其它类型的文件会访问失败。如果跟我一样图片都在子路径 img
下,就写 www.example.com/img/*
。

配置好之后按照正常的 URL 访问就可以压缩图片了,压缩失败的会使用原图。