如何在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
相关产品推荐
相关产品推荐

