函数变量

更新时间:
复制 MD 格式

边缘函数在运行时需要读取源站用户名、第三方服务密钥等配置,将这些配置直接写死在代码中既不安全,也让同一份代码无法在测试和生产之间复用。函数变量是承载在边缘函数上的键值对,支持将配置从代码中剥离出来单独维护,敏感值可加密存储,仅函数代码可以访问。函数变量在构建、边缘函数、云函数三个环节均可生效:构建流水线执行的构建任务可作为构建期环境变量参与打包,边缘函数运行时通过 env 读取,云函数则按标准 Node.js 环境变量方式读取。

说明

函数变量同样可适用于构建流水线。

变量、环境与版本的对应关系

在配置变量之前,先了解以下三条规则,可以避免"改了变量但函数读不到新值"这类问题。

  • 按环境独立存储:变量分别存放在生产环境和测试环境中。同一个变量键可以在两个环境中同时存在并取不同的值,修改或删除只作用于当前所在的环境,另一个环境中的同名变量不受影响。

  • 在下一次版本部署后生效:新增或修改变量不会立刻作用于线上正在运行的函数,需要重新生成版本并把该版本发布到对应环境,函数代码才能读到新值。

  • 版本绑定变量快照:生成版本时可以选择绑定某个环境的变量快照,绑定后这个版本只能发布到对应环境;不绑定变量的版本可以发布到任意环境。版本的生成与发布流程可参见版本管理。

添加函数变量

  1. 登录ESA控制台,在左侧导航栏选择边缘计算和 AI > 函数和Pages。

  2. 单击目标函数名称进入函数详情页,选择基本信息页签,在页面下方找到函数变量区域。

  3. 在函数变量区域上方选择要写入的环境页签,默认停留在生产环境,需要维护测试环境的变量时切换到测试环境。页签切换后列表会重新加载该环境下的变量,搜索词也会被清空。

  4. 单击添加变量,在添加变量对话框中按下表填写。

    参数

    说明

    键

    变量键,函数代码按此名称读取变量值。只能包含字母、数字和下划线,__proto__、constructor、prototype 为保留名称不可使用。同一次提交中不允许出现重复的变量键。变量键创建后无法修改,只能删除后重新创建。

    值

    变量值。勾选加密存储时可以留空。

    加密存储

    勾选后变量值以加密形式存储,列表中不再显示明文。适用于密钥、令牌等敏感配置。加密存储的变量在控制台不再回显明文,但在函数代码中读取时仍然拿到解密后的明文值。

    环境

    勾选变量生效的环境

变量与环境、分支、发布的绑定关系

配置函数变量时必须选择生效环境,环境的选择直接决定了变量与代码分支、以及可发布目标环境之间的绑定关系:

  • 生产环境的函数变量默认与生产分支绑定。由生产分支构建生成的版本,只能发布到生产环境,运行时读取到的是生产环境下配置的变量。

  • 测试环境的函数变量默认与非生产分支绑定。由非生产分支构建生成的版本,仅允许发布到测试环境,运行时读取到的是测试环境下配置的变量。

因此,同一个变量键可以在生产环境与测试环境配置为不同的值(例如指向不同的数据库或第三方地址),代码无需改动,即可随所在分支/环境自动读取到对应的取值。若某个键只在其中一个环境配置、而在另一个环境缺失,则对应环境的代码读取该键时会得到 undefined(详见下文异常说明)。

环境

绑定分支

可发布目标

典型用途

生产环境

生产分支

仅生产环境

线上正式配置

测试环境

非生产分支

仅测试环境

联调/测试配置

在边缘函数中使用

边缘函数运行时通过 env 对象读取函数变量。无论该键在控制台是明文还是加密存储,代码中读取到的都是解密后的明文值。引擎采用惰性解析(仅解析代码中实际用到的 env.key),因此建议只读取需要的键,避免下发过多变量影响冷启动。

通过 fetch 入口函数参数获取

// 控制台配置:
// TEST_KEY_PLAIN  明文
// TEST_KEY_SECRET 加密

export default {
  async fetch(request, context, env) {  # 注意 env 是 fetch 的第三个参数
    const TEST_KEY_PLAIN = env.TEST_KEY_PLAIN;
    const TEST_KEY_SECRET = env.TEST_KEY_SECRET;

    return new Response(
      `Get TEST_KEY_PLAIN: ${TEST_KEY_PLAIN} and TEST_KEY_SECRET: ${TEST_KEY_SECRET} successfully!`
    );
  },
};

通过 import 方式加载

除入口参数外,也可以从 alibaba:workers 模块导入 env,适用于在入口函数之外的全局作用域或工具模块中读取变量。

全局 import:

import { env } from "alibaba:workers";

const TEST_KEY_PLAIN = env.TEST_KEY_PLAIN;
const TEST_KEY_SECRET = env.TEST_KEY_SECRET;

export default {
  async fetch(request, context) {
    return new Response(
      `Get TEST_KEY_PLAIN: ${TEST_KEY_PLAIN} and TEST_KEY_SECRET: ${TEST_KEY_SECRET} successfully!`
    );
  },
};

函数内部 import:

export default {
  async fetch(request, context) {
    const { env } = await import("alibaba:workers");
    const TEST_KEY_PLAIN = env.TEST_KEY_PLAIN;
    const TEST_KEY_SECRET = env.TEST_KEY_SECRET;

    return new Response(
      `Get TEST_KEY_PLAIN: ${TEST_KEY_PLAIN} and TEST_KEY_SECRET: ${TEST_KEY_SECRET} successfully!`
    );
  },
};

在云函数中使用

云函数中函数变量即标准的 Node.js 环境变量,通过 process.env 读取:

export default (req, res) => {
  const testKeyPlain = process.env.TEST_KEY_PLAIN;
  const testKeySecret = process.env.TEST_KEY_SECRET;

  res.send(
    `Get TEST_KEY_PLAIN: ${testKeyPlain} and TEST_KEY_SECRET: ${testKeySecret} successfully!`
  );
};

加密存储的变量在云函数中读取到的同样是解密后的明文值。

常见问题