📝 前提条件
在开始前,你需要准备好:
一个 Cloudflare 账户,并将你的自定义域名接入 Cloudflare 管理(NS 服务器已切换至 Cloudflare)。
一个已激活的 Free.fr Pages Perso 空间,并知道其原始访问地址(例如 yourid.free.fr)。
如需强制 HTTPS,请确保你的 Free.fr 空间已启用 HTTPS。Free.fr 现已支持 HTTPS 访问,地址格式为 https://yourid.pages-perso.free.fr。
🛠️ 详细操作步骤
步骤一:创建 Cloudflare Worker
登录 Cloudflare Dashboard,在左侧菜单中进入 “Workers 和 Pages”。
点击 “创建应用程序” -> “创建 Worker”。
为你的 Worker 命名(例如 free-proxy),然后点击 “部署”。
部署后,点击 “编辑代码” 进入代码编辑器。
步骤二:配置反向代理代码
将编辑器中的默认代码全部删除,替换为以下反向代理代码:
// 用户请求时,你想要代理的上游网站(即你的 Free.fr 地址)const upstream = 'yourid.free.fr'; // ⚠️ 替换为你的 Free.fr 域名,不加 http://
// 上游网站的自定义路径(通常保持 '/' 即可)
const upstream_path = '/';
// 移动端设备代理的上游网站(通常与上方保持一致)
const upstream_mobile = 'yourid.free.fr'; // ⚠️ 替换为你的 Free.fr 域名
// 希望暂停服务的国家和地区代码(保持空数组即可)
const blocked_region = [];
// 希望禁止访问的 IP 地址(保持默认即可)
const blocked_ip_address = ['0.0.0.0', '127.0.0.1'];
// 是否对上游地址使用 HTTPS 协议
// 如果你的 Free.fr 空间已支持 HTTPS,建议设为 true
const https = false; // ⚠️ 根据你的 Free.fr 空间是否支持 HTTPS 来设置
// 是否禁用缓存
const disable_cache = false;
// 文本替换规则:将上游域名替换为你的自定义域名
const replace_dict = {
'$upstream': '$custom_domain',};
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request));});
async function fetchAndApply(request) {
const region = request.headers.get('cf-ipcountry')?.toUpperCase() || '';
const ip_address = request.headers.get('cf-connecting-ip') || '';
const user_agent = request.headers.get('user-agent') || '';
let response = null;
let url = new URL(request.url);
let url_hostname = url.hostname;
// 根据 https 常量决定上游协议
if (https == true) {
url.protocol = 'https:';
} else {
url.protocol = 'http:';
}
// 根据设备类型选择上游域名
if (await device_status(user_agent)) {
var upstream_domain = upstream;
} else {
var upstream_domain = upstream_mobile;
}
url.host = upstream_domain;
// 处理路径
if (url.pathname == '/') {
url.pathname = upstream_path;
} else {
url.pathname = upstream_path + url.pathname;
}
// 地区/ IP 封锁检查
if (blocked_region.includes(region)) {
response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
status: 403
});
} else if (blocked_ip_address.includes(ip_address)) {
response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
status: 403
});
} else {
let method = request.method;
let request_headers = request.headers;
let new_request_headers = new Headers(request_headers);
// 设置转发请求的关键头部
new_request_headers.set('Host', upstream_domain);
new_request_headers.set('Referer', url.protocol + '//' + upstream_domain);
let data = {};
if (method == 'POST') {
let origin_formData = await request.text();
data = {
method: method,
headers: new_request_headers,
body: origin_formData
};
} else if (method == 'GET') {
data = {
method: method,
headers: new_request_headers
};
}
// 发起上游请求
let original_response = await fetch(url.href, data);
// 处理 WebSocket 升级(如有需要)
let connection_upgrade = new_request_headers.get("Upgrade");
if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") {
return original_response;
}
// 克隆响应,以便修改头部和内容
let original_response_clone = original_response.clone();
let original_text = null;
let response_headers = original_response.headers;
let new_response_headers = new Headers(response_headers);
let status = original_response.status;
if (disable_cache) {
new_response_headers.set('Cache-Control', 'no-store');
}
// 设置 CORS 头部,允许跨域
new_response_headers.set('access-control-allow-origin', '*');
new_response_headers.set('access-control-allow-credentials', true);
// 删除可能导致问题的安全头部
new_response_headers.delete('content-security-policy');
new_response_headers.delete('content-security-policy-report-only');
new_response_headers.delete('clear-site-data');
// 获取响应文本,进行内容替换(关键步骤)
const content_type = new_response_headers.get('content-type');
if (content_type && content_type.includes('text/html')) {
original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
} else {
original_text = original_response_clone.body;
}
// 返回修改后的响应
response = new Response(original_text, {
status,
headers: new_response_headers
});
}
return response;}
// 判断是否为移动设备
async function device_status(user_agent_info) {
var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (var v = 0; v < agents.length; v++) {
if (user_agent_info.indexOf(agents[v]) > 0) {
flag = false;
break;
}
}
return flag;}
// 替换响应文本中的域名
async function replace_response_text(response, upstream_domain, host_name) {
let text = await response.text();
var i, j;
for (i in replace_dict) {
j = replace_dict[i];
if (i == '$upstream') {
i = upstream_domain;
} else if (i == '$custom_domain') {
i = host_name;
}
if (j == '$upstream') {
j = upstream_domain;
} else if (j == '$custom_domain') {
j = host_name;
}
let re = new RegExp(i, 'g');
text = text.replace(re, j);
}
return text;}
关键修改点:
将 const upstream = 'yourid.free.fr'; 中的 yourid.free.fr 替换为你的 Free.fr 实际域名。
同样地,将 const upstream_mobile = 'yourid.free.fr'; 也进行替换。
如果你的 Free.fr 空间支持 HTTPS,建议将 const https = false; 改为 const https = true;,以增强安全性。
修改完成后,点击右上角的 “保存并部署”。
步骤三:绑定自定义域名
在 Worker 的管理界面,点击 “设置” 选项卡。
选择 “域和路由” -> “添加” -> “自定义域”。
输入你想要绑定的子域名(例如 free.yourdomain.com),然后点击 “添加域”。Cloudflare 会自动为你处理 SSL 证书,无需手动配置。
