1. Cloudflare Workers介绍

    Cloudflare Workers 是 Cloudflare 提供的一种边缘计算运行环境,用于在接近用户的位置执行自定义代码,从而对 HTTP 请求与响应进行处理。可以实现轻量的后端。

  2. 目标功能

    实现激活码校验功能,并能够在cf后台更改。

    即微信小程序/本地发送一个HTTP请求,然后通过cf workers脚本和env变量校验,返回对应的消息,完成校验。管理者可以通过修改env变量来实现对激活码的更改。

  3. 一些必要的概念介绍

    1. URL:

      我参考了什么是 URL? - 学习 Web 开发 | MDN的讲解。下面我简单地介绍脚本当中要用到的内容。

      简单地说URL就是web地址,俗称“网址”。

      给出一个例子:https://activation-code.electro-dragon.site/?activationCode=2026

      字段 含义 补充描述
      https 方案 一般web采用https或者http
      electro-dragon.site 主域名 其中site是顶级域名,electro-dragon为二级域名
      activation-code 子域名 理论上可无限扩展。与主域名结合,指向不同的地址。
      ?activationCode=2026 查询参数 由问号开头,提供给服务器的额外参数。可以由客户端构建,服务端校验。
    2. URL的searchParams方法

      searchParams:一个 URLSearchParams 对象,用于以键值对的方式访问查询参数。在这篇文章中很重要,也是唯一要用的URL方法。

      下面是一些针对searchParams的方法:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      //根据name获取单个参数,返回字符串或 null
      searchParams.get(name);

      //判断是否存在
      searchParams.has(name);

      //三种迭代方法,返回一个迭代器,用于迭代key,value,所有键值对
      searchParams.keys()
      searchParams.values()
      searchParams.entries()

      其中,迭代器概念是最不好理解的。

      同样给出参考文章,供查询:

      然后,我们先做一个尝试:使用console.log()打印任一迭代器。以entries()为例子。

      你将在控制台中看到一个EntryIterator,可以将其展开,但没有值。

      我们用一个类比来解释。

      你去牛杂店铺里吃牛杂。你需要告诉老板:“来一份牛杂”,然后老板会在做菜后返回需要的牛杂。(for...of等消费行为)

      而不是找到老板,看看老板,发现原来是刻师傅。(console.log())

      你感叹:她真好看。

      但你无法得到想要的牛杂。

      上面这个例子中,点餐就是消费迭代器的过程。控制台不会替你调用迭代器并迭代,它只会告诉你打印的是什么。需要手动消费迭代器,才能得到值。

      下面结合先前的例子,给出三种常用的消费办法:

      1
      2
      3
      4
      5
      6
      7
      8
      //next方法,得到下一个值
      const value = searchParams.entries().next()

      //for...of循环,遍历迭代器中的每个值
      for (const value of searchParams.entries()) {}

      //扩展运算符,展开迭代器所有值,存在一个数组里
      const value = [...searchParams.entries()]
    3. Cloudflare Workers 默认模板

      默认模板,即hello world模板如下。

      1
      2
      3
      4
      5
      6
      7
      export default {
      async fetch(request, env, ctx) {
      // You can view your logs in the Observability dashboard
      console.info({ message: 'Hello World Worker received a request!' });
      return new Response('Hello World!');
      }
      };

      需要理解其中前两个参数requestenv的用法。

      • request

        我们使用console.log(request)打印这个参数。可以得到:

        1
        {method: 'GET', url: 'https://activation-code.electro-dragon.site/?activationCode=2026', headers: Headers, redirect: 'manual', fetcher: Fetcher, …}

        其中url是我们需要的参数。我们需要通过下面的语句 new 一个url。

        1
        const url = new URL(request.url);

        如果你对 JS 有所了解,但尚未接触HTTP协议、URL解析的内容,或许会疑惑:

        为什么不直接写const url = request.url,而是要 new一个呢?

        因为const url = request.url得到的是一个字符串,不是一个URL对象。那么我们只能通过split这类方法对其切割,而无法对其使用searchParams方法,来提取我们所需的查询参数。

      • env

        这是 Cloudflare Workers 提供的环境变量。需要在对应 Workers 的设置页面手动配置和更新。然后会在收到请求时自动把变量注入 fetch 。

  4. 实现办法

    因为这并不是纯新手教程,默认你已经拥有cloudflare账户,语言为简中,并且了解一些基础操作

    1. 进入Workers 和 Pages页面。

    2. 点击右上角蓝色图标创建应用程序

    3. 选择从Hello World!开始

    4. 编辑Wroker name,当然不编辑也行,只要你记得住。

    5. 不需要改Wroker preview,点击部署

    6. 展开的界面如下。

    7. 进入设置界面。

    8. 变量和机密中,添加JSON类型的变量。

    9. 如果您拥有自己的域名,且已代理到Cloudflare,您还可以在此界面的域和路由区域,添加您的自定义域。

    10. 进入概述界面。点击右上角的编辑代码,进入代码编辑窗口。

    参考代码如下,您可以直接引用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    export default {
    async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const params = url.searchParams;
    const entries = [...params.entries()]; //因为只有一对查询参数键值对,所以这里直接展开迭代器

    //查询参数缺失
    if(entries.length == 0) {
    return Response.json({
    success: false,
    error: "missing parameters"
    },{status: 400});
    }

    const [key, code] = entries[0];

    //env中不包含的键名
    if (!(key in env)) {
    return Response.json({
    success: false,
    error: "unknow app name"
    },{status: 400});
    }

    const success = (code == env[key]);

    return Response.json({
    success: success,
    message: success ? "Activation code is valid" : "Activation code mismatch"
    },{status: 200});

    }
    };
    1. 构建符合要求的URL,点击右上角的刷新按钮进行测试。如图。结果也会在右侧控制台输出。

    2. 客户端可以通过判断返回的内容,获知激活码是否正确。此处不展开。