跳过导航
返回

CloudFlare Worker链接加速工具:原理详解与完整代码

编辑页面

什么是链接加速工具?

链接加速工具是一个基于CloudFlare Workers构建的无服务器代理服务,它能帮助用户绕过跨域限制、加速文件下载,并提供简洁的用户界面。这个工具特别适合处理需要移除Origin、Referer等HTTP头限制的资源访问场景。

核心工作原理

1. 整体架构

用户请求 → CloudFlare Worker → 目标服务器 → 返回给用户

这个工具充当了一个”智能中间人”的角色,在用户和目标服务器之间转发请求,同时进行必要的HTTP头修改。

2. 关键功能模块

2.1 请求拦截与处理

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

这是Worker的标准入口点,拦截所有发送到Worker的请求。

2.2 URL解析流程

输入URL示例: https://your-worker.workers.dev/https://example.com/file.zip
处理过程:
1. 解析Worker域名后面的部分: /https://example.com/file.zip
2. 提取实际目标URL: https://example.com/file.zip
3. 向目标URL发起请求

2.3 HTTP头修改机制

// 特殊规则配置
const specialCases = [
  {
    pattern: /.*/,  // 匹配所有域名
    rules: {
      "Origin": "DELETE",    // 删除Origin头
      "Referer": "DELETE"    // 删除Referer头
    }
  }
]

这个配置会自动移除跨域限制相关的HTTP头,解决CORS(跨源资源共享)问题。

3. 安全防护体系

3.1 黑名单系统

// 黑名单配置(支持正则表达式)
const blacklist = []

// 预编译黑名单正则表达式
const blacklistRegex = blacklist.map(item => {
  if (item.includes('.*')) {
    const pattern = item.replace(/\./g, '\\.').replace(/\*/g, '.*');
    return new RegExp(`^(.*\\.)?${pattern}$`);
  }
  // ... 其他匹配逻辑
});

黑名单系统支持多种匹配模式:

3.2 白名单机制

白名单的优先级高于黑名单,可用于设置例外。

3.3 文件名安全处理

function getFilenameFromUrl(url) {
  // 从URL路径、查询参数中提取文件名
  // 安全过滤:移除非法文件名字符
  return decodeURIComponent(filename)
    .replace(/[<>:"/\\|?*]/g, '_')
    .trim() || 'download';
}

4. 内容类型识别

工具能智能识别是否为可下载文件:

5. 前端界面

工具提供响应式Web界面,支持:

完整代码

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

// 特殊规则配置
const specialCases = [
  {
    pattern: /.*/,
    rules: {
      "Origin": "DELETE",
      "Referer": "DELETE"
    }
  }
]

// 黑名单配置
const blacklist = []

// 白名单
const whitelist = []

// 简约首页HTML
const homepageHTML = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>链接加速工具</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; background: #f5f5f5; }
        .container { background: white; border-radius: 8px; padding: 30px; margin-top: 40px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
        h1 { text-align: center; margin-bottom: 20px; font-size: 24px; color: #333; }
        .description { text-align: center; color: #666; margin-bottom: 30px; }
        .input-group { margin-bottom: 20px; }
        input[type="url"] { width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
        input[type="url"]:focus { outline: none; border-color: #0066cc; }
        button { width: 100%; padding: 12px; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; background: #0066cc; color: white; }
        button:hover { opacity: 0.9; }
        .info-box { background: #f8f9fa; padding: 15px; border-radius: 4px; border-left: 4px solid #0066cc; margin: 20px 0; }
        .info-box h3 { margin-bottom: 10px; font-size: 16px; }
        .usage { margin: 30px 0; }
        .usage h3 { margin-bottom: 10px; }
        code { background: #f8f9fa; padding: 2px 4px; border-radius: 3px; font-family: 'Monaco', 'Menlo', monospace; font-size: 14px; }
        .warning { background: #fff3cd; border: 1px solid #ffc107; padding: 15px; border-radius: 4px; margin: 20px 0; }
        .footer { text-align: center; color: #666; font-size: 14px; margin-top: 30px; }
    </style>
</head>
<body>
    <div class="container">
        <h1>链接加速工具</h1>
        <p class="description">移除跨域限制,加速下载链接</p>
        
        <div class="input-group">
            <input type="url" id="url-input" placeholder="https://example.com/file.zip" autocomplete="off">
        </div>
        
        <button onclick="downloadFile()">开始加速下载</button>
        
        <div class="info-box">
            <h3>功能说明</h3>
            <p>• 移除Origin、Referer等跨域限制</p>
            <p>• 自动保持原始文件名</p>
            <p>• 支持HTTP/HTTPS链接</p>
        </div>
        
        <div class="usage">
            <h3>使用方法</h3>
            <p>1. 在输入框中粘贴链接</p>
            <p>2. 点击"开始加速下载"按钮</p>
            <p>3. 或者直接在URL后追加要加速的链接:</p>
            <p><code>https://worker.workers.dev/https://example.com/file.zip</code></p>
        </div>
        
        <div class="warning">
            <p><strong>⚠️ 注意:</strong>请勿用于访问非法或侵权内容。</p>
        </div>
        
        <div class="footer">
            <p>© 2026 链接加速工具</p>
        </div>
    </div>
    
    <script>
        function getWorkerUrl() { return window.location.origin + '/'; }
        
        function downloadFile() {
            const input = document.getElementById('url-input');
            const url = input.value.trim();
            if (!url) { alert('请输入链接地址'); input.focus(); return; }
            if (!isValidUrl(url)) { alert('请输入有效的链接'); return; }
            
            const iframe = document.createElement('iframe');
            iframe.style.display = 'none';
            iframe.src = getWorkerUrl() + encodeURIComponent(url);
            document.body.appendChild(iframe);
            setTimeout(() => iframe.remove(), 10000);
        }
        
        function isValidUrl(string) {
            try { new URL(string); return true; } 
            catch (_) { return false; }
        }
        
        document.getElementById('url-input').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') downloadFile();
        });
        
        document.addEventListener('DOMContentLoaded', () => {
            document.getElementById('url-input').focus();
        });
    </script>
</body>
</html>`;

// 预编译黑名单正则表达式
const blacklistRegex = blacklist.map(item => {
  if (item.includes('.*')) {
    const pattern = item.replace(/\./g, '\\.').replace(/\*/g, '.*');
    return new RegExp(`^(.*\\.)?${pattern}$`);
  } else if (item.includes('/')) {
    const pattern = item.replace(/\./g, '\\.').replace(/\*/g, '.*');
    return item.startsWith('http') 
      ? new RegExp(`^${pattern}`)
      : new RegExp(`^https?://${pattern}`);
  } else {
    const pattern = item.replace(/\./g, '\\.');
    return new RegExp(`^(.*\\.)?${pattern}$`);
  }
});

// 从URL中提取文件名
function getFilenameFromUrl(url) {
  try {
    const urlObj = new URL(url);
    const pathname = urlObj.pathname;
    let filename = pathname.split('/').pop();
    
    if (!filename || !filename.includes('.')) {
      filename = 'download';
      const queryParams = ['filename', 'file', 'name', 'download'];
      for (const param of queryParams) {
        const value = urlObj.searchParams.get(param);
        if (value) { filename = value; break; }
      }
    }
    
    return decodeURIComponent(filename)
      .replace(/[<>:"/\\|?*]/g, '_')
      .trim() || 'download';
  } catch {
    return 'download';
  }
}

// 检查URL是否在黑名单中
function isBlacklisted(url) {
  const hostname = url.hostname;
  return blacklistRegex.some(regex => regex.test(hostname)) && 
         !whitelist.some(whiteItem => hostname === whiteItem || hostname.endsWith('.' + whiteItem));
}

// 处理特殊规则
function handleSpecialCases(request) {
  for (const { pattern, rules } of specialCases) {
    if (pattern.test(new URL(request.url).hostname)) {
      for (const [key, value] of Object.entries(rules)) {
        if (value === "DELETE") {
          request.headers.delete(key);
        } else if (value !== "KEEP") {
          request.headers.set(key, value);
        }
      }
      break;
    }
  }
}

// 创建通用的响应头
function createCommonHeaders(originalHeaders = {}) {
  const headers = new Headers({
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
    'Access-Control-Allow-Headers': '*',
    'X-Content-Type-Options': 'nosniff',
    'X-Frame-Options': 'DENY',
    ...originalHeaders
  });
  return headers;
}

// 主请求处理函数
async function handleRequest(request) {
  const url = new URL(request.url);
  
  // 处理根路径
  if (url.pathname === "/" || url.pathname === "/index.html") {
    return new Response(homepageHTML, {
      headers: {
        'Content-Type': 'text/html;charset=UTF-8',
        'Cache-Control': 'no-cache',
        'X-Frame-Options': 'DENY',
        'X-Content-Type-Options': 'nosniff'
      }
    });
  }
  
  try {
    // 获取实际URL
    const actualUrlStr = decodeURIComponent(url.pathname.slice(1) + url.search + url.hash);
    const actualUrl = new URL(actualUrlStr);
    
    // 检查黑名单
    if (isBlacklisted(actualUrl)) {
      return new Response(
        JSON.stringify({ error: "访问被拒绝", message: "该域名已被列入黑名单" }),
        { 
          status: 403, 
          headers: createCommonHeaders({ 'Content-Type': 'application/json' })
        }
      );
    }
    
    // 创建修改后的请求
    const modifiedRequest = new Request(actualUrl, {
      headers: request.headers,
      method: request.method,
      body: request.body,
      redirect: 'follow'
    });
    
    // 处理特殊规则
    handleSpecialCases(modifiedRequest);
    
    // 添加默认User-Agent
    if (!modifiedRequest.headers.has('User-Agent')) {
      modifiedRequest.headers.set('User-Agent', 
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    }
    
    // 获取响应
    const response = await fetch(modifiedRequest);
    
    // 判断是否为可下载文件
    const contentType = response.headers.get('content-type') || '';
    const isDownloadable = 
      /^(application|audio|video|image)\//.test(contentType) ||
      (contentType.includes('text/') && !contentType.includes('text/html')) ||
      response.headers.get('content-disposition')?.includes('attachment');
    
    // 创建响应头
    const responseHeaders = createCommonHeaders(response.headers);
    
    if (isDownloadable) {
      const filename = getFilenameFromUrl(actualUrlStr);
      const encodedFilename = encodeURIComponent(filename);
      responseHeaders.set('Content-Disposition', 
        `attachment; filename="${encodedFilename}"; filename*=UTF-8''${encodedFilename}`);
      responseHeaders.set('Cache-Control', 'public, max-age=86400');
    }
    
    return new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: responseHeaders
    });
    
  } catch (error) {
    return new Response(
      JSON.stringify({ error: "无效的URL", message: "请输入有效的HTTP/HTTPS链接" }),
      { 
        status: 400, 
        headers: createCommonHeaders({ 'Content-Type': 'application/json' })
      }
    );
  }
}

部署步骤

1. 准备工作

2. 创建Worker

  1. 登录CloudFlare仪表板
  2. 进入”Workers & Pages”页面
  3. 点击”创建Worker”
  4. 将完整代码复制到编辑器
  5. 点击”部署”

3. 配置自定义域名(可选)

  1. 在Worker设置中点击”触发器”
  2. 添加自定义域名
  3. 按照提示配置DNS记录

使用示例

方式1:Web界面

1. 访问你的Worker域名
2. 输入目标URL
3. 点击"开始加速下载"

方式2:直接调用

https://your-worker.workers.dev/https://example.com/file.zip
https://your-worker.workers.dev/https://video.example.com/video.mp4

技术亮点

1. 无服务器架构优势

2. 安全性设计

3. 性能优化

应用场景

1. 文件下载加速

2. 媒体资源访问

3. API代理

注意事项

1. 合法使用

2. 性能限制

3. 安全建议

扩展可能性

1. 添加缓存功能

// 在响应处理中添加缓存控制
responseHeaders.set('Cache-Control', 'public, max-age=3600');

2. 添加用户认证

// 简单的Token验证
const validTokens = ['your-secret-token'];
const token = request.headers.get('X-Auth-Token');
if (!validTokens.includes(token)) {
  return new Response('Unauthorized', { status: 401 });
}

3. 添加日志记录

// 记录请求信息
console.log(JSON.stringify({
  timestamp: new Date().toISOString(),
  clientIP: request.headers.get('CF-Connecting-IP'),
  targetUrl: actualUrl.href,
  userAgent: request.headers.get('User-Agent')
}));

总结

这个CloudFlare Worker链接加速工具展示了一个实用的无服务器代理实现。它结合了:

  1. 前端交互界面 - 提供用户友好的操作界面
  2. 代理转发功能 - 核心的请求转发机制
  3. 安全防护机制 - 多层次的安全保护
  4. 智能处理逻辑 - 自动识别文件类型和设置相应头

通过这个工具,开发者可以学习到:

这个项目不仅可以直接使用,还可以作为学习无服务器代理开发的基础模板,根据自己的需求进行修改和扩展。


注意:使用代理工具时,请确保遵守目标网站的服务条款和相关法律法规。本工具仅供技术学习和合法用途。


编辑页面
分享到:

下一篇
在 Flutter 中运行 JavaScript:flutter_js 完全指南