能否在单个CNAME下对两个目标进行A/B测试并实现动态路由?
A/B Testing & Dynamic Routing Under a Single CNAME with Cloudflare Workers
Absolutely, you can pull off both A/B testing and dynamic routing for your two Heroku apps under the fixed app.domain.com CNAME using Cloudflare Workers. This is actually a common, well-suited use case for Workers—they let you intercept and redirect requests on the fly while keeping the user-facing URL completely unchanged.
How to Make This Work
1. Pre-Setup in Cloudflare
- First, configure
app.domain.comas a CNAME record in Cloudflare’s DNS panel. You can point it to either of your Heroku apps (e.g.,a-test.herokuapp.com)—the Worker will override this target anyway. - Make sure the orange cloud proxy status is enabled for this record so requests pass through Cloudflare’s network.
2. Create a Cloudflare Worker with Routing Logic
Build a new Worker and use this code to handle traffic splitting and user stickiness (so users stay in the same test group on repeat visits):
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { // Check if the user already has a test group cookie const cookieHeader = request.headers.get('Cookie') let targetHost = 'a-test.herokuapp.com' // Default to control group // Assign or retain the user's test group if (cookieHeader && cookieHeader.includes('ab_test_group=b')) { targetHost = 'b-test.herokuapp.com' } else if (!cookieHeader || Math.random() < 0.5) { // 50% chance to assign to B group (adjust 0.5 to tweak split ratio) targetHost = 'b-test.herokuapp.com' } // Modify the request to point to the target Heroku app const modifiedRequest = new Request(request.url, { method: request.method, headers: new Headers(request.headers), body: request.body, redirect: 'follow' }) modifiedRequest.headers.set('Host', targetHost) // Fetch the response from the target app const response = await fetch(modifiedRequest) // Create a new response to set/update the test group cookie (30-day expiry) const finalResponse = new Response(response.body, response) const groupValue = targetHost === 'b-test.herokuapp.com' ? 'b' : 'a' finalResponse.headers.set( 'Set-Cookie', `ab_test_group=${groupValue}; Path=/; Max-Age=2592000; SameSite=Lax` ) return finalResponse }
3. Key Code Breakdown
- User Stickiness: The
ab_test_groupcookie ensures users stay in their assigned group for 30 days (adjustMax-Ageto change this duration). - Traffic Split: The
Math.random() < 0.5line sets a 50/50 split—tweak the decimal value (e.g.,0.3for 30% traffic to the B group) to match your test needs. - Invisible Routing: By modifying the
Hostheader, we send the request to the correct Heroku app while keepingapp.domain.comvisible to the user.
Official Cloudflare Resources
You can dive deeper into relevant topics in Cloudflare’s official docs:
- Worker Fetch API: Learn how to intercept and modify requests/responses.
- Cookie Handling in Workers: Best practices for setting and managing user cookies.
- A/B Testing Recipes: Cloudflare provides pre-built examples for A/B testing scenarios in their Workers guide.
Quick Notes
- Ensure your Heroku apps allow CORS requests from
app.domain.com(update their CORS settings if you run into cross-origin errors). - Bind the Worker to the
app.domain.com/*route in Cloudflare’s Worker dashboard to activate it for all requests to your domain.
内容的提问来源于stack exchange,提问作者bteng22
相关产品推荐
相关产品推荐

