设为首页收藏本站

ZMX - IT技术交流论坛 - 无限Perfect,追求梦想 - itzmx.com

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

搜索
查看: 3667|回复: 1

Cloudflare cf使用workers搭建一个简单的免费页面反代系统,不符合HTTP协议标准规范但是能凑合用,腾讯云函数已经收费

[复制链接]
 成长值: 339

签到天数: 4738 天

[LV.Master]伴坛终老

发表于 2022/3/19 06:15 | 显示全部楼层 |阅读模式 |Google Chrome 99.0.4844.51|Windows 10
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
Cloudflare cf使用workers搭建一个简单的免费页面反代系统,不符合HTTP协议标准规范但是能凑合用,腾讯云函数已经收费

比如说,刚刚更新了下方代码,符合HTTP协议标准,已经支持响应206状态码
放入workers即可使用,无需更改。注意绑定自己的自定义域名。

  1. addEventListener('fetch', event => {
  2.     event.passThroughOnException()
  3.   
  4.     event.respondWith(handleRequest(event))
  5.   })
  6.   
  7.   /**
  8.   * Respond to the request
  9.   * @param {Request} request
  10.   */
  11.   async function handleRequest(event) {
  12.     const { request } = event;
  13.   
  14.     //请求头部、返回对象
  15.     let reqHeaders = new Headers(request.headers),
  16.         outBody, outStatus = 200, outStatusText = 'OK', outCt = null, outHeaders = new Headers({
  17.             "Access-Control-Allow-Origin": reqHeaders.get('Origin'),
  18.             "Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS",
  19.             "Access-Control-Allow-Headers": reqHeaders.get('Access-Control-Allow-Headers') || "Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token, Notion-Version"
  20.         });
  21.   
  22.     try {
  23.         //取域名第一个斜杠后的所有信息为代理链接
  24.         let url = request.url.substr(8);
  25.         url = decodeURIComponent(url.substr(url.indexOf('/') + 1));
  26.   
  27.         //需要忽略的代理
  28.         if (request.method == "OPTIONS" && reqHeaders.has('access-control-request-headers')) {
  29.             //输出提示
  30.             return new Response(null, PREFLIGHT_INIT)
  31.         }
  32.         else if(url.length < 3 || url.indexOf('.') == -1 || url == "favicon.ico" || url == "robots.txt") {
  33.             return Response.redirect('https://baidu.com', 301)
  34.         }
  35.         //阻断
  36.         else if (blocker.check(url)) {
  37.             return Response.redirect('https://baidu.com', 301)
  38.         }
  39.         else {
  40.             //补上前缀 http://
  41.             url = url.replace(/https:(\/)*/,'https://').replace(/http:(\/)*/, 'http://')
  42.             if (url.indexOf("://") == -1) {
  43.                 url = "http://" + url;
  44.             }
  45.             //构建 fetch 参数
  46.             let fp = {
  47.                 method: request.method,
  48.                 headers: {}
  49.             }
  50.   
  51.             //保留头部其它信息
  52.             let he = reqHeaders.entries();
  53.             for (let h of he) {
  54.                 if (!['content-length'].includes(h[0])) {
  55.                     fp.headers[h[0]] = h[1];
  56.                 }
  57.             }
  58.             // 是否带 body
  59.             if (["POST", "PUT", "PATCH", "DELETE"].indexOf(request.method) >= 0) {
  60.                 const ct = (reqHeaders.get('content-type') || "").toLowerCase();
  61.                 if (ct.includes('application/json')) {
  62.                       let requestJSON = await request.json()
  63.                       console.log(typeof requestJSON)
  64.                     fp.body = JSON.stringify(requestJSON);
  65.                 } else if (ct.includes('application/text') || ct.includes('text/html')) {
  66.                     fp.body = await request.text();
  67.                 } else if (ct.includes('form')) {
  68.                     fp.body = await request.formData();
  69.                 } else {
  70.                     fp.body = await request.blob();
  71.                 }
  72.             }
  73.             // 发起 fetch
  74.             let fr = (await fetch(url, fp));
  75.             outCt = fr.headers.get('content-type');
  76.             if(outCt && (outCt.includes('application/text') || outCt.includes('text/html'))) {
  77.               try {
  78.                 // 添加base
  79.                 let newFr = new HTMLRewriter()
  80.                 .on("head", {
  81.                   element(element) {
  82.                     element.prepend(`<base href="${url}" />`, {
  83.                       html: true
  84.                     })
  85.                   },
  86.                 })
  87.                 .transform(fr)
  88.                 fr = newFr
  89.               } catch(e) {
  90.               }
  91.             }

  92.             for (const [key, value] of fr.headers.entries()) {
  93.               outHeaders.set(key, value);
  94.             }

  95.             outStatus = fr.status;
  96.             outStatusText = fr.statusText;
  97.             outBody = fr.body;
  98.         }
  99.     } catch (err) {
  100.         outCt = "application/json";
  101.         outBody = JSON.stringify({
  102.             code: -1,
  103.             msg: JSON.stringify(err.stack) || err
  104.         });
  105.     }
  106.   
  107.     //设置类型
  108.     if (outCt && outCt != "") {
  109.         outHeaders.set("content-type", outCt);
  110.     }
  111.   
  112.     let response = new Response(outBody, {
  113.         status: outStatus,
  114.         statusText: outStatusText,
  115.         headers: outHeaders
  116.     })
  117.   
  118.     return response;
  119.   
  120.     // return new Response('OK', { status: 200 })
  121.   }
  122.   
  123.   /**
  124.   * 阻断器
  125.   */
  126.   const blocker = {
  127.     keys: [".m3u8", ".ts", ".acc", ".m4s", "photocall.tv", "googlevideo.com"],
  128.     check: function (url) {
  129.         url = url.toLowerCase();
  130.         let len = blocker.keys.filter(x => url.includes(x)).length;
  131.         return len != 0;
  132.     }
  133.   }
复制代码



workers反代使用方式
  1. https://workers绑定的自定义域名/https://bmd.itzmx.com/static/image/common/logo.png
复制代码



反代支持301跳转跟随来始终以https发起,目标域名不带http和带http均为http发起(如果301则为https发起),目标带https时候则强制以https发起(会校验TLS证书有效性,不允许反代目标域名为自签名)
cf反代回源站所传递的ip地址:2a06:98c0:3600::103
Cloudflare customer zone, the CF-Connecting-IP value will be set to the Worker client IP address '2a06:98c0:3600::103' for security reasons.
数据来自官方文档:https://developers.cloudflare.com/workers/runtime-apis/headers/

提醒,请勿滥用,cf反代服务器每天限量10W次下载,每日早晨8点刷新配额。
CF反代代码没做ip地址支持,仅支持域名,反代能访问 1.1.1.1 1.1.1.2 1.1.1.3 1.0.0.1 1.0.0.2 1.0.0.3 这几个ip,其它ip都不允许直接访问
https://反代地址/https://1.1.1.1/cdn-cgi/trace 可以改成这样用来检测cf反代在线状态,非200状态码代表无法使用。反代超10W每日配额时是输出429状态码。

腾讯云函数也可以实现相同的效果:https://curl.qcloud.com/W4ANcAUL
但是收费了就不介绍了。


自己有服务器,想用kangle搭建一个网络更快的,只需操作文章中说的“国内服务器"
https://bbs.itzmx.com/thread-100060-1-1.html

用kangle自建时建议hosts文件绑定国内备案域名用国内反代服务器,需要使用https,例如反代地址 pikpak.oss-cn-hangzhou.aliyuncs.com 证书文件要在电脑上受信一下
https://bbs.itzmx.com/thread-90800-1-1.html

一个生成的证书例子:https://bbs.itzmx.com/thread-90896-1-1.html

既然有反代那就要有屏蔽的方法
网站屏蔽Cloudflare cf使用workers搭建的反代爬虫bot,REMOTE_ADDR header头部禁止 2a06:98c0:3600::103 ipv6地址,非真实浏览器禁止访问
https://bbs.itzmx.com/thread-101376-1-1.html

评分

参与人数 1樱币 +1 收起 理由
ricroon + 1 很给力!

查看全部评分

欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复

使用道具 举报

签到天数: 234 天

[LV.7]常住居民III

发表于 2022/3/19 15:28 | 显示全部楼层 |Firefox 99.0|Windows 10
小樱啥时候出个比特彗星下载百度网盘的完整教程鸭
[发帖际遇]: oitre 在论坛发帖时没有注意,被小偷偷去了 2 樱币. 幸运榜 / 衰神榜
欢迎光临IT技术交流论坛:http://bbs.itzmx.com/
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册论坛 新浪微博账号登陆用百度帐号登录

本版积分规则

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2024/12/24 01:24 , Processed in 0.226352 second(s), 19 queries , MemCache On.

Powered by itzmx! X3.4

© 2011- sakura

快速回复 返回顶部 返回列表