中国的网络环境封闭了各大国外的网站,导致下载一些内容会出错。这时候需要用cloudflare worker进行代理下载。
在 Compute -> Workers & Pages 下面创建一个worker。
输入下面的简单代码就可以实现一个代理下载功能。支持设置token防止别人乱用。
export default {
async fetch(request) {
const url = new URL(request.url);
const MY_TOKEN = 'yourtoken'; // 设置成自己的token,防止别人滥用
const token = url.searchParams.get('token');
if (token !== MY_TOKEN) {
return new Response('Unauthorized: Invalid or missing token', { status: 401 });
}
const targetUrl = url.searchParams.get('url');
if (!targetUrl) {
return new Response('No valid target address!', { status: 400 });
}
// 向目标地址请求文件
const fileResponse = await fetch(targetUrl, {
method: 'GET',
redirect: 'follow'
});
// 直接从 URL 里提取文件名(取最后一段)
const fileName = targetUrl.split('/').pop() || 'downloadfile';
return new Response(fileResponse.body, {
status: 200,
headers: {
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${fileName}"`
}
});
}
}将worker绑定自己的域名后。就可以进行使用了。
比如下载文件:https://example.com/file.zip,使用方法是把目标链接加上自己的域名前缀:
https://yourdomain.com/?token=yourtoken&url=https://example.com/file.zip
经过我测试。下载sourceforge、github文件和huggingface.co的模型文件全都可以加速。比如使用aria2c下载huggingface的AI模型能达到3-5MB/S的速度
我准备把这个简单的地址转换功能做成一个简单的网站页面随时使用。为了防止很多人找到这个页面而滥用免费次数(虽然CF很慷慨)。可以不给这个页面任何站内链接让它成为孤立的隐藏页面。只有自己知道访问地址。
我发现之前的代码太过简单不支持续传请求,所以修改了一下,支持基础的断点续传。
export default {
async fetch(request) {
const url = new URL(request.url);
const MY_TOKEN = 'yourtoken';
const token = url.searchParams.get('token');
if (token !== MY_TOKEN) {
return new Response('Unauthorized: Invalid or missing token', { status: 401 });
}
const targetUrl = url.searchParams.get('url');
if (!targetUrl) {
return new Response('No valid target address!', { status: 400 });
}
// 获取原始请求的Range头
const rangeHeader = request.headers.get('Range');
// 构建转发请求的headers
const headers = new Headers();
if (rangeHeader) {
headers.set('Range', rangeHeader);
}
// 向目标地址请求文件
const fileResponse = await fetch(targetUrl, {
method: 'GET',
headers: headers,
redirect: 'follow'
});
// 获取Content-Length(如果存在)
const contentLength = fileResponse.headers.get('Content-Length');
const contentRange = fileResponse.headers.get('Content-Range');
const status = fileResponse.status;
// 检查是否返回了部分内容
const isPartial = status === 206;
// 直接从 URL 里提取文件名
const fileName = targetUrl.split('/').pop() || 'downloadfile';
// 构建响应headers
const responseHeaders = new Headers({
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${fileName}"`,
'Accept-Ranges': 'bytes'
});
// 如果是范围请求,传递Content-Range和Content-Length
if (isPartial) {
if (contentRange) {
responseHeaders.set('Content-Range', contentRange);
}
if (contentLength) {
responseHeaders.set('Content-Length', contentLength);
}
}
// 返回响应
return new Response(fileResponse.body, {
status: isPartial ? 206 : 200,
headers: responseHeaders
});
}
}