无登录Cloudflare Workers Proxy Code

person 元章 event 2026-03-06 local_offer 代码 chat 评论
代码展示
export default {
  async fetch(request) {
    const url = new URL(request.url);
    const proxyBase = url.origin + '/';
    
    // 获取用户想要访问的路径和参数
    let targetUrlStr = url.pathname.slice(1) + url.search;

    // 核心补丁:如果请求路径不是以 http 开头(说明代理前缀丢失了)
    if (!targetUrlStr.startsWith('http')) {
      // 尝试从 Referer (来源页面) 中抢救目标域名
      const referer = request.headers.get('Referer');
      if (referer && referer.startsWith(proxyBase)) {
        try {
          // 提取上一个页面的目标网址
          const refererTarget = new URL(referer).pathname.slice(1);
          if (refererTarget.startsWith('http')) {
            const baseTargetOrigin = new URL(refererTarget).origin;
            // 拼接丢失的域名和当前请求的相对路径
            const fixedPath = targetUrlStr.startsWith('/') ? targetUrlStr : '/' + targetUrlStr;
            const recoveredUrl = baseTargetOrigin + fixedPath;
            
            // 极其重要:强制浏览器重定向到完整的代理地址,拯救代理会话!
            return Response.redirect(proxyBase + recoveredUrl, 302);
          }
        } catch (e) {
          // 解析来源失败,忽略
        }
      }

      // 如果连 Referer 都没有,且路径为空,才显示主页 UI
      if (!targetUrlStr || targetUrlStr === '') {
        return new Response(generateUI(url.origin), {
          headers: { 'Content-Type': 'text/html; charset=utf-8' }
        });
      }
    }

    // 正常代理逻辑继续...
    try {
      const targetUrl = new URL(targetUrlStr);
      const newHeaders = new Headers(request.headers);
      
      newHeaders.set('Host', targetUrl.hostname);
      newHeaders.set('Origin', targetUrl.origin);
      newHeaders.set('Referer', targetUrl.origin + '/');
      newHeaders.delete('X-Forwarded-For');
      newHeaders.delete('CF-Connecting-IP');

      const response = await fetch(targetUrl.href, {
        method: request.method,
        headers: newHeaders,
        body: request.method !== 'GET' && request.method !== 'HEAD' ? await request.clone().arrayBuffer() : null,
        redirect: 'manual'
      });

      const responseHeaders = new Headers(response.headers);

      // 处理 301/302 重定向
      if (responseHeaders.has('Location')) {
        let location = responseHeaders.get('Location');
        try {
          const absoluteLocation = new URL(location, targetUrl.href).href;
          responseHeaders.set('Location', proxyBase + absoluteLocation);
        } catch (e) {}
      }

      // 处理 Cookie,维持基本会话
      if (responseHeaders.has('Set-Cookie')) {
        const cookies = responseHeaders.get('Set-Cookie');
        const modifiedCookies = cookies.replace(/domain=[^;]+/gi, '').replace(/path=[^;]+/gi, 'path=/');
        responseHeaders.set('Set-Cookie', modifiedCookies);
      }

      // 暴力解除安全头
      responseHeaders.set('Access-Control-Allow-Origin', '*');
      responseHeaders.delete('Content-Security-Policy');
      responseHeaders.delete('X-Frame-Options');

      const contentType = responseHeaders.get('Content-Type') || '';

      // 只有 HTML 才重写和注入 JS
      if (contentType.includes('text/html')) {
        class AttributeRewriter {
          constructor(attributeName) { this.attributeName = attributeName; }
          element(element) {
            const attributeValue = element.getAttribute(this.attributeName);
            if (attributeValue && !attributeValue.startsWith('#') && !attributeValue.startsWith('data:') && !attributeValue.startsWith('javascript:')) {
              try {
                const absoluteUrl = new URL(attributeValue, targetUrl.href).href;
                element.setAttribute(this.attributeName, proxyBase + absoluteUrl);
              } catch (e) {}
            }
          }
        }

        // 注入 JS 拦截器,解决动态请求跨域问题
        class JSInjector {
          element(element) {
            const script = `
              <script>
                (function() {
                  const proxyBase = '${proxyBase}';
                  const targetOrigin = '${targetUrl.origin}';
                  
                  const originalFetch = window.fetch;
                  window.fetch = async function() {
                    let args = arguments;
                    if (typeof args[0] === 'string' && args[0].startsWith('/')) {
                      args[0] = proxyBase + targetOrigin + args[0];
                    }
                    return originalFetch.apply(this, args);
                  };

                  const originalOpen = XMLHttpRequest.prototype.open;
                  XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
                    if (typeof url === 'string' && url.startsWith('/')) {
                      url = proxyBase + targetOrigin + url;
                    }
                    return originalOpen.call(this, method, url, async, user, password);
                  };
                })();
              </script>
            `;
            element.prepend(script, { html: true });
          }
        }

        let rewriter = new HTMLRewriter()
          .on('head', new JSInjector())
          .on('a', new AttributeRewriter('href'))
          .on('img', new AttributeRewriter('src'))
          .on('link', new AttributeRewriter('href'))
          .on('script', new AttributeRewriter('src'))
          .on('form', new AttributeRewriter('action'));

        return rewriter.transform(new Response(response.body, {
          status: response.status,
          headers: responseHeaders
        }));
      }

      // 非 HTML 资源直接返回
      return new Response(response.body, {
        status: response.status,
        headers: responseHeaders
      });

    } catch (e) {
      return new Response(`代理出错: ${e.message}`, { status: 500 });
    }
  }
};

function generateUI(origin) {
  return `
  <!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>
      body { font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f2f5; margin: 0; }
      .container { background: white; padding: 2rem; border-radius: 10px; text-align: center; width: 90%; max-width: 500px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); }
      input { width: 100%; padding: 12px; margin: 10px 0; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; }
      button { width: 100%; padding: 12px; background: #007bff; color: white; border: none; border-radius: 6px; cursor: pointer; }
    </style>
  </head>
  <body>
    <div class="container">
      <h2>🌐 完美代理增强版</h2>
      <form id="proxyForm">
        <input type="url" id="targetUrl" placeholder="输入网址 (需带 https://)" required>
        <button type="submit">开始无障碍浏览</button>
      </form>
    </div>
    <script>
      document.getElementById('proxyForm').addEventListener('submit', function(e) {
        e.preventDefault();
        window.location.href = '${origin}/' + document.getElementById('targetUrl').value;
      });
    </script>
  </body>
  </html>
  `;
}

copyright 版权声明

相关文章

评论