CF反向代理方法

/**
 * Cloudflare Worker 反向代理
 */

// 目标网站地址
const TARGET_HOST = '地址';  // 是目标地址
const TARGET_URL = `https://${TARGET_HOST}`;

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

/**
 * 处理请求的核心函数
 */
async function handleRequest(request) {
  try {
    // 1. 解析请求的 URL
    const url = new URL(request.url);

    // 2. 构建目标 URL(保持原始路径和查询参数)
    const targetUrl = `${TARGET_URL}${url.pathname}${url.search}`;

    // 3. 复制并修改请求头
    const headers = new Headers(request.headers);
    headers.set('Host', TARGET_HOST);
    
    // 保留重要的请求头
    headers.set('Origin', TARGET_URL);
    headers.set('Referer', TARGET_URL + '/');

    // 4. 构建请求选项(关键修复:保留请求体)
    const requestOptions = {
      method: request.method,
      headers: headers,
      redirect: 'manual',
    };

    // ★ 关键修复:处理请求体(支持 POST/PUT/PATCH 等方法)
    if (request.method !== 'GET' && request.method !== 'HEAD') {
      // 克隆请求体(因为 body 只能读取一次)
      const body = await request.clone().arrayBuffer();
      if (body.byteLength > 0) {
        requestOptions.body = body;
      }
    }

    // 5. 发起代理请求
    const response = await fetch(targetUrl, requestOptions);

    // 6. 处理重定向
    if ([301, 302, 303, 307, 308].includes(response.status)) {
      const location = response.headers.get('Location');
      if (location) {
        // 如果重定向到外部,直接转发
        const responseHeaders = new Headers(response.headers);
        responseHeaders.set('Access-Control-Allow-Origin', '*');
        return new Response(response.body, {
          status: response.status,
          statusText: response.statusText,
          headers: responseHeaders
        });
      } else {
        return new Response('网站不允许代理访问', {
          status: 200,
          headers: { 'Content-Type': 'text/plain; charset=utf-8' }
        });
      }
    }

    // 7. 处理 SSE (Server-Sent Events) 流式响应
    const contentType = response.headers.get('Content-Type') || '';
    
    if (contentType.includes('text/event-stream') || 
        response.headers.get('Transfer-Encoding') === 'chunked') {
      // 对于流式响应,直接透传
      const responseHeaders = new Headers(response.headers);
      responseHeaders.set('Access-Control-Allow-Origin', '*');
      responseHeaders.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
      responseHeaders.set('Cache-Control', 'no-cache');
      responseHeaders.set('Connection', 'keep-alive');
      
      return new Response(response.body, {
        status: response.status,
        statusText: response.statusText,
        headers: responseHeaders
      });
    }

    // 8. 处理普通响应
    const responseHeaders = new Headers(response.headers);
    responseHeaders.set('Access-Control-Allow-Origin', '*');
    responseHeaders.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    responseHeaders.set('Access-Control-Allow-Headers', '*');

    // 删除冲突的安全头
    responseHeaders.delete('Content-Security-Policy');
    responseHeaders.delete('X-Frame-Options');

    // 9. 返回响应
    return new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: responseHeaders
    });

  } catch (error) {
    return new Response(`代理失败: ${error.message}`, {
      status: 500,
      headers: { 'Content-Type': 'text/plain; charset=utf-8' }
    });
  }
}
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容