因为一些特殊原因,我有一个比较小众的需求:希望利用CDN的边缘函数来缓存一个外部文件。可能大多数人用不到,但还是记录一下这个思路。
最开始的想法很简单,通过边缘函数实现一个跳转。当用户访问 a.com/logo.jpg
时,自动跳转到 b.com/logo.jpg
。这样就能在不存储该文件的情况下,依然使用 a.com/logo.jpg
的路径访问它。
如果只是跳转,访问体验其实不太好,毕竟多了一次重定向。于是想到,是否可以直接让 CDN 缓存 b.com/logo.jpg
,这样访问 a.com/logo.jpg
时,就能直接从缓存中获取,而不用每次都请求源站。
最终实现的代码如下:
// 目标图片地址
const targetUrl = 'https://b.com/logo.jpg';
async function handleRequest(request) {
const url = new URL(request.url);
if (url.pathname === '/logo.jpg') {
// 构造新请求,避免原始请求的 headers 影响缓存
const newRequest = new Request(targetUrl, {
headers: new Headers({
'User-Agent': request.headers.get('User-Agent')
})
});
// 从源站获取图片
const response = await fetch(newRequest);
// 创建一个可缓存的响应
const cachedResponse = new Response(response.body, {
status: response.status,
headers: {
'Content-Type': response.headers.get('Content-Type'),
'Cache-Control': 'public, max-age=86400' // 缓存 1 天
}
});
return cachedResponse;
}
// 其他请求正常处理
return fetch(request);
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
这样,每次访问 a.com/logo.png
,CDN 都会从缓存中直接返回图片,提高访问速度。如果缓存过期,CDN 会自动从 b.com
获取最新的文件并重新缓存。
整体来说,这个方法适用于那些无法在源站存储文件,但又希望使用特定域名访问的场景。虽然是个小众需求,但或许对部分人来说有参考价值。
The End