在本指南中,你将了解如何在 Pages 项目中使用 Pages Functions 进行 A/B 测试。A/B 测试是一种用户体验研究方法,用于比较网页或应用的两个或多个版本。通过 A/B 测试,你可以向用户提供网页的多个版本,并分配站点流量。
为 A/B 测试配置应用的不同版本取决于你的具体用例。对所有开发者而言,A/B 测试设置可简化为几个实用原则。
根据应用版本数量(本指南使用两个),你可以将用户分配到实验组。本指南中的实验组为基础路由 / 和测试路由 /test。
为确保用户保持在分配的组中,你将在浏览器中设置并存储 Cookie,并根据设置的 Cookie 值提供相应的路由。
在项目中,你可以使用 Pages Functions 处理 A/B 测试逻辑。Pages Functions 允许你在 Pages 项目内处理服务端逻辑。
开始步骤:
- 前往本地机器上的 Pages 项目目录。
- 创建
/functions目录。应用服务端逻辑将位于/functions目录中。
Pages Functions 具有可复用逻辑块的实用函数,这些逻辑在路由处理程序之前和/或之后执行。这些称为中间件。按照本指南,中间件允许你在请求到达站点之前拦截对 Pages 项目的请求。
在 /functions 目录中,创建 _middleware.js 文件。
按照 Functions 命名约定,_middleware.js 文件导出一个接受 request、env 和 next 作为参数的异步 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];在项目中设置 functions/_middleware.js 文件后,即可使用 Pages 部署。将项目更改推送到 GitHub/GitLab。
部署应用后,查看中间件 Function:
-
在 Cloudflare 仪表板中,前往 Workers & Pages 页面。
Go to Workers & Pages ↗ -
选择你的 Pages 项目 > Settings(设置) > Functions(函数) > Configuration(配置)。