• Orwells

    在开始之前,请注意以下问题:

    - Cloudflare 的ToS中禁止了这类代理加速的用途,可能会导致你CF账号封禁

    - 可能会导致你的云盘账号风控甚至封禁

    - AlistGo/alist-proxy 此仓库已经长时间未更新,未来可能不再适配

    - OpenList 目前大概率可以使用

    为什么要使用CF Worker代理下载?

    1. 节省VPS资源

    对于部分只能本机代理的云盘,代理下载走的是CF。所以如果你VPS带宽很小或者流量很少/流量很贵,走代理地址下载就可以不走你的VPS了。

    图片

    2. 解决跨网限速

    对于天翼云盘跨网QoS可能是一个解决办法。

    相关帖子

    https://linux.do/t/topic/693929

    使用要求

    使用CF Worker加速需要满足以下条件:

    - Cloudflare 账号

    - 暴露在公网的Alist

    - 最好还需要一个托管在CF账号的域名(Worker提供的域名被墙了)

    一、Cloudflare部分

    1. 创建Worker项目

    点击创建项目:

    图片

    点击开始使用:

    图片

    填写项目名:

    图片

    2. 编辑代码

    编辑代码:

    图片

    worker.zip (1.6 KB)

    复制代码到CF的编辑器中,你也可以直接worker.zip (1.6 KB)

    该代码来自 AlistGo/alist-proxy

    你也可以直接复制

    worker.js```
    // src/const.ts
    var ADDRESS = "YOUR_ADDRESS";
    var TOKEN = "YOUR_TOKEN";
    var WORKER_ADDRESS = "YOUR_WORKER_ADDRESS";

    // src/verify.ts
    var verify = async (data, _sign) => {
    const signSlice = _sign.split(":");
    if (!signSlice[signSlice.length - 1]) {
    return "expire missing";
    }
    const expire = parseInt(signSlice[signSlice.length - 1]);
    if (isNaN(expire)) {
    return "expire invalid";
    }
    if (expire < Date.now() / 1e3 && expire > 0) {
    return "expire expired";
    }
    const right = await hmacSha256Sign(data, expire);
    if (_sign !== right) {
    return "sign mismatch";
    }
    return "";
    };
    var hmacSha256Sign = async (data, expire) => {
    const key = await crypto.subtle.importKey(
    "raw",
    new TextEncoder().encode(TOKEN),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["sign", "verify"]
    );
    const buf = await crypto.subtle.sign(
    {
    name: "HMAC",
    hash: "SHA-256"
    },
    key,
    new TextEncoder().encode(${data}:${expire})
    );
    return btoa(String.fromCharCode(...new Uint8Array(buf))).replace(/\+/g, "-").replace(/\//g, "_") + ":" + expire;
    };

    // src/handleDownload.ts
    async function handleDownload(request) {
    const origin = request.headers.get("origin") ?? "*";
    const url = new URL(request.url);
    const path = decodeURIComponent(url.pathname);
    const sign = url.searchParams.get("sign") ?? "";
    const verifyResult = await verify(path, sign);
    if (verifyResult !== "") {
    const resp2 = new Response(
    JSON.stringify({
    code: 401,
    message: verifyResult
    }),
    {
    headers: {
    "content-type": "application/json;charset=UTF-8"
    }
    }
    );
    resp2.headers.set("Access-Control-Allow-Origin", origin);
    return resp2;
    }
    let resp = await fetch(${ADDRESS}/api/fs/link, {
    method: "POST",
    headers: {
    "content-type": "application/json;charset=UTF-8",
    Authorization: TOKEN
    },
    body: JSON.stringify({
    path
    })
    });
    let res = await resp.json();
    if (res.code !== 200) {
    return new Response(JSON.stringify(res));
    }
    request = new Request(res.data.url, request);
    if (res.data.header) {
    for (const k in res.data.header) {
    for (const v of res.data.header[k]) {
    request.headers.set(k, v);
    }
    }
    }
    let response = await fetch(request);
    while (response.status >= 300 && response.status < 400) {
    const location = response.headers.get("Location");
    if (location) {
    if (location.startsWith(${WORKER_ADDRESS}/)) {
    request = new Request(location, request);
    return await handleRequest(request);
    } else {
    request = new Request(location, request);
    response = await fetch(request);
    }
    } else {
    break;
    }
    }
    response = new Response(response.body, response);
    response.headers.delete("set-cookie");
    response.headers.set("Access-Control-Allow-Origin", origin);
    response.headers.append("Vary", "Origin");
    return response;
    }

    // src/handleOptions.ts
    function handleOptions(request) {
    const corsHeaders = {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS",
    "Access-Control-Max-Age": "86400"
    };
    let headers = request.headers;
    if (headers.get("Origin") !== null && headers.get("Access-Control-Request-Method") !== null) {
    let respHeaders = {
    ...corsHeaders,
    "Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers") || ""
    };
    return new Response(null, {
    headers: respHeaders
    });
    } else {
    return new Response(null, {
    headers: {
    Allow: "GET, HEAD, POST, OPTIONS"
    }
    });
    }
    }

    // src/handleRequest.ts
    async function handleRequest(request) {
    if (request.method === "OPTIONS") {
    return handleOptions(request);
    }
    return await handleDownload(request);
    }

    // src/index.ts
    var src_default = {
    async fetch(request, env, ctx) {
    return await handleRequest(request);
    }
    };
    export {
    src_default as default
    };
    //# sourceMappingURL=index.js.map
    ```3. 配置参数

    代码中有三个值需要我们填写,分别是 ADDRESS、TOKEN、WORKER_ADDRESS:

    图片

    - ADDRESS: 你部署的Alist的下载地址

    - WORKER_ADDRESS: 你创建的Worker地址(如果你稍后要绑定域名,填写你需要绑定的域名)

    - TOKEN: Alist的Token,可以在Alist的设置里面找到

    获取Alist Token

    在Alist的设置页面可以找到Token:

    图片

    填写配置

    按照如下图填写参数:

    图片

    点击右上角部署完成之后,就可以关掉Cloudflare的网页了。

    二、Alist部分

    配置存储

    以天翼云盘为例,填写完其他部分后,把WebDAV策略改成使用代理地址,并把你的Worker地址填写在下载代理URL中:

    图片

    Web代理可以根据自己需要勾选,一般情况下不用。详见相关文档

    当然,你也可以自己使用服务器代理流量,相关文档请参考:

    下载代理URL文档

    验证

    这是一个非常简单的教程。为了验证天翼云盘代理下载是否能解决跨网限速问题,我提供一个下载速度测试地址:

    电信302跳转下载链接

    CF代理下载链接-需要挂代理

    上面两个是在claw cloud跑的临时Alist,文件是ubuntu镜像,各位可以自行测试速度是否有用,以及我同时也测试一下会不会风控。挂载的天翼云盘账号为2T空间/无会员

    worker.js 是怎样运行的

    先验证请求是否合法```
    const verifyResult = await verify(path, sign);

    
    2. 向Alist请求下载链接```
    let resp = await fetch(`${ADDRESS}/api/fs/link`, {
      method: "POST",
      headers: {
        "content-type": "application/json;charset=UTF-8",
        Authorization: TOKEN
      },
      body: JSON.stringify({ path })
    });
    ```调用Alist的`/api/fs/link`接口获取下载链接
    
    3. 代理下载```
    request = new Request(res.data.url, request);
    let response = await fetch(request);
    ```获取到真实下载链接后:```
    while (response.status >= 300 && response.status < 400) {
      const location = response.headers.get("Location");
      if (location.startsWith(`${WORKER_ADDRESS}/`)) {
        return await handleRequest(request);
      } else {
        request = new Request(location, request);
        response = await fetch(request);
      }
    }
    ``````
    response.headers.delete("set-cookie");
    response.headers.set("Access-Control-Allow-Origin", origin);
    response.headers.append("Vary", "Origin");
    主楼
  • 方块

    感谢分享!

    #1
  • 芍霾🏆

    感谢分享。

    #2
  • YaoOnion

    感谢分享!

    #3
  • 韩老魔

    感谢分享

    #4
  • 士多啤梨味香蕉雪

    天翼死号才敢用

    #5
  • Finn

    感谢分享!!!

    #6
  • Orwells

    对的 我挂载测试是就是咸鱼买的 几块钱一个10T 自己号还是算了

    #7
  • 大帅哥

    感谢大佬教程!

    #8
  • lonner

    Mark

    #9
  • 深度索饮

    感谢分享,对我来说门槛有点高,看看教程支持一下,谢谢!

    #10
  • hlnvci

    感谢分享,请问这样下载速度能有多少?

    #11
  • Orwells

    你可以在文中找到我提供的测试下载链接试试 天翼云盘套cf

    #12
  • MysteryQ

    佬,想问下这种方式为什么会导致网盘被风控呢^-^

    #13
  • Orwells

    多数挂载的云盘本身就是逆向的接口,并且cloudflare worker都是cloudflare的ip当然容易被风控了

    #14

发表回复

登录后回复