You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cloudflare Worker中用Fetch API实现类cURL的代理请求?

解决方案

一、核心差异:cURL与Worker请求的本质区别

你用cURL执行的是标准HTTP CONNECT代理请求,而Worker代码里是直接把代理服务器当作目标服务器发送GET请求,两者的请求逻辑完全不同,这是导致失败的核心原因。

二、可行实现方案

1. 手动构造CONNECT请求建立隧道

如果你的代理服务器支持HTTP CONNECT方法,可以在Worker中手动建立隧道,再通过隧道发送目标请求:

export default async function fetch(request, env, ctx) {
  const proxyHost = "<proxy_url>:<proxy_port>";
  const targetHost = "ipinfo.io";
  const targetPath = "/"; // 可根据需求修改

  // 第一步:发送CONNECT请求建立代理隧道
  const connectResp = await fetch(`https://${proxyHost}`, {
    method: "CONNECT",
    headers: {
      "Host": targetHost,
      "Proxy-Authorization": "Basic <token_here>",
    },
    redirect: "manual",
  });

  // 检查隧道是否建立成功
  if (connectResp.status !== 200) {
    return new Response(`代理隧道建立失败:${connectResp.status}`, { status: 502 });
  }

  // 第二步:通过隧道发送目标GET请求
  const { readable, writable } = connectResp.body;
  const writer = writable.getWriter();
  
  // 构造符合HTTP协议的请求报文
  const requestMsg = `GET ${targetPath} HTTP/1.1\r\n` +
                     `Host: ${targetHost}\r\n` +
                     `User-Agent: curl/7.81.0\r\n` +
                     `Accept: */*\r\n\r\n`;
  
  // 写入请求到隧道
  await writer.write(new TextEncoder().encode(requestMsg));
  writer.releaseLock();

  // 返回代理返回的响应流
  return new Response(readable, {
    status: 200,
    headers: { "Content-Type": "text/plain" },
  });
}

2. 检查代理服务器的防火墙规则

你遇到的521错误和防火墙提示,大概率是因为:

  • cURL请求来自你的本地IP,而Worker请求来自Cloudflare的公共IP段
  • 代理服务器的防火墙仅允许特定IP(如你的本地IP)访问,拒绝了Cloudflare的IP

解决方式:联系代理服务器管理员,将Cloudflare Worker的IP段加入白名单,或更换支持Cloudflare IP访问的代理服务。

3. 替代方案:利用Cloudflare原生能力减少代理依赖

如果你的场景是访问公开资源,可以考虑:

  • 使用Cloudflare Worker KV或R2缓存静态资源,避免重复代理请求
  • 直接通过Cloudflare网络访问目标服务(Cloudflare的全球网络覆盖广,多数公开服务无需额外代理即可访问)

内容的提问来源于stack exchange,提问作者IngilizAdam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:23:16