跳转到内容
搜索文档

在 Pages 中使用 Pages Functions 进行 A/B 测试

最后更新 查看 MarkdownAgent 设置

在本指南中,你将了解如何在 Pages 项目中使用 Pages Functions 进行 A/B 测试。A/B 测试是一种用户体验研究方法,用于比较网页或应用的两个或多个版本。通过 A/B 测试,你可以向用户提供网页的多个版本,并分配站点流量。

概览

为 A/B 测试配置应用的不同版本取决于你的具体用例。对所有开发者而言,A/B 测试设置可简化为几个实用原则。

根据应用版本数量(本指南使用两个),你可以将用户分配到实验组。本指南中的实验组为基础路由 / 和测试路由 /test

为确保用户保持在分配的组中,你将在浏览器中设置并存储 Cookie,并根据设置的 Cookie 值提供相应的路由。

设置 Pages Function

在项目中,你可以使用 Pages Functions 处理 A/B 测试逻辑。Pages Functions 允许你在 Pages 项目内处理服务端逻辑。

开始步骤:

  1. 前往本地机器上的 Pages 项目目录。
  2. 创建 /functions 目录。应用服务端逻辑将位于 /functions 目录中。

添加中间件逻辑

Pages Functions 具有可复用逻辑块的实用函数,这些逻辑在路由处理程序之前和/或之后执行。这些称为中间件。按照本指南,中间件允许你在请求到达站点之前拦截对 Pages 项目的请求。

/functions 目录中,创建 _middleware.js 文件。

按照 Functions 命名约定,_middleware.js 文件导出一个接受 requestenvnext 作为参数的异步 onRequest 函数。

const abTest = async ({ request, next, env }) => {
	/*
  Todo:
  1. Conditional statements to check for the cookie
  2. Assign cookies based on percentage, then serve
  */
};

export const onRequest = [abTest];

要设置 Cookie,创建 cookieName 变量并赋值;然后创建 newHomepagePathName 变量并赋值为 /test

const cookieName = "ab-test-cookie";
const newHomepagePathName = "/test";

const abTest = async ({ request, next, env }) => {
	/*
  Todo:
  1. Conditional statements to check for the cookie
  2. Assign cookie based on percentage then serve
  */
};

export const onRequest = [abTest];

设置条件逻辑

根据 URL 路径名,检查 Cookie 值是否等于 new。若值为 new,则提供 newHomepagePathName

const cookieName = "ab-test-cookie";
const newHomepagePathName = "/test";

const abTest = async ({ request, next, env }) => {
	/*
  Todo:
  1. Assign cookies based on randomly generated percentage, then serve
  */

	const url = new URL(request.url);
	if (url.pathname === "/") {
		// if cookie ab-test-cookie=new then change the request to go to /test
		// if no cookie set, pass x% of traffic and set a cookie value to "current" or "new"

		let cookie = request.headers.get("cookie");
		// is cookie set?
		if (cookie && cookie.includes(`${cookieName}=new`)) {
			// Change the request to go to /test (as set in the newHomepagePathName variable)
			url.pathname = newHomepagePathName;
			return env.ASSETS.fetch(url);
		}
	}
};

export const onRequest = [abTest];

若 Cookie 值不存在,需要分配一个。使用 Math.floor(Math.random() * 100) 生成 0-99 的百分比。默认 Cookie 版本值为 current

若生成的百分比低于 50,将 Cookie 版本分配为 new。根据随机生成的百分比,设置 Cookie 并提供资源。条件块之后,将请求传递给 next()。这将把请求传递给 Pages。结果是 50% 的用户将获得 /test 主页。

env.ASSETS.fetch() 函数允许你通过 url 参数将用户发送到修改后的路径。env 是包含环境变量和绑定的对象。ASSETS 是默认 Function 绑定,允许 Function 与 Pages 资源提供资源通信。fetch() 调用 Pages 资源提供资源并返回资源(/test 主页)给网站访问者。

const cookieName = "ab-test-cookie";
const newHomepagePathName = "/test";

const abTest = async (context) => {
	const url = new URL(context.request.url);
	// if homepage
	if (url.pathname === "/") {
		// if cookie ab-test-cookie=new then change the request to go to /test
		// if no cookie set, pass x% of traffic and set a cookie value to "current" or "new"

		let cookie = request.headers.get("cookie");
		// is cookie set?
		if (cookie && cookie.includes(`${cookieName}=new`)) {
			// pass the request to /test
			url.pathname = newHomepagePathName;
			return context.env.ASSETS.fetch(url);
		} else {
			const percentage = Math.floor(Math.random() * 100);
			let version = "current"; // default version
			// change pathname and version name for 50% of traffic
			if (percentage < 50) {
				url.pathname = newHomepagePathName;
				version = "new";
			}
			// get the static file from ASSETS, and attach a cookie
			const asset = await context.env.ASSETS.fetch(url);
			let response = new Response(asset.body, asset);
			response.headers.append("Set-Cookie", `${cookieName}=${version}; path=/`);
			return response;
		}
	}
	return context.next();
};

export const onRequest = [abTest];

部署到 Cloudflare Pages

在项目中设置 functions/_middleware.js 文件后,即可使用 Pages 部署。将项目更改推送到 GitHub/GitLab。

部署应用后,查看中间件 Function:

  1. 在 Cloudflare 仪表板中,前往 Workers & Pages 页面。

    Go to Workers & Pages ↗
  2. 选择你的 Pages 项目 > Settings(设置) > Functions(函数) > Configuration(配置)

这篇文档对您有帮助吗?