Always await or waitUntil Promises
A Promise that is not awaited, returned, or passed to ctx.waitUntil() is a floating promise. Floating promises cause silent bugs: dropped results, swallowed errors, and unfinished work. The Workers runtime may terminate your isolate before a floating promise completes. Choose based on whether the response depends on the work: use await or return for work that must complete before the response is correct; use ctx.waitUntil() for work that can run after the response is sent and finishes within the waitUntil() time limit. Enable the no-floating-promises lint rule to catch these at development time.
Do not store request-scoped state in global scope
Workers reuse isolates across requests. A variable set during one request is still present during the next. This causes cross-request data leaks, stale state, and "Cannot perform I/O on behalf of a different request" errors. Pass state through function arguments or store it on env bindings. Never use module-level variables for request-scoped data.
Build notification customization
The Workers template for build notifications can be customized to format messages for different webhook providers beyond the default Slack and Discord integrations.
Deploy from Slack slash command example
A Worker that receives a /deploy command from Slack and triggers a build:
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const body = await request.formData();
const command = body.get("command");
const token = body.get("token");
if (token !== env.SLACK_VERIFICATION_TOKEN) {
return new Response("Unauthorized", { status: 401 });
}
if (command === "/deploy") {
const res = await fetch(env.DEPLOY_HOOK_URL, { method: "POST" });
const { result } = await res.json<{ result: { build_uuid: string } }>();
return new Response(`Build started: ${result.build_uuid}`);
}
return new Response("Unknown command", { status: 400 });
},
};
Rebuild on a schedule example
A Worker with a Cron Trigger that rebuilds every hour:
export default {
async scheduled(event: ScheduledEvent, env: Env): Promise<void> {
await fetch(env.DEPLOY_HOOK_URL, { method: "POST" });
},
};
Early Hints Hono framework implementation example
Example of implementing Early Hints in a Cloudflare Worker using Hono:
import { Hono } from "hono";
const app = new Hono();
const CSS = "body { color: red; }";
const HTML = `
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Early Hints test</title>
<link rel="stylesheet" href="/test.css">
</head>
<body>
<h1>Early Hints test page</h1>
</body>
</html>
`;
// Serve CSS file
app.get("/test.css", (c) => {
return c.body(CSS, {
headers: {
"content-type": "text/css",
},
});
});
// Serve HTML with early hints
app.get("*", (c) => {
return c.html(HTML, {
headers: {
link: "</test.css>; rel=preload; as=style",
},
});
});
export default app;
Early Hints Link header format
The Link header format for Early Hints is: link: "</path/to/asset>; rel=preload; as=style" (or other asset type). This tells the browser to preload the asset while waiting for the HTML response.
Early Hints TypeScript implementation example
Example of implementing Early Hints in a Cloudflare Worker using TypeScript:
const CSS = "body { color: red; }";
const HTML = `
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Early Hints test</title>
<link rel="stylesheet" href="/test.css">
</head>
<body>
<h1>Early Hints test page</h1>
</body>
</html>
`;
export default {
async fetch(req): Promise<Response> {
// If request is for test.css, serve the raw CSS
if (/test\.css$/.test(req.url)) {
return new Response(CSS, {
headers: {
"content-type": "text/css",
},
});
} else {
// Serve raw HTML using Early Hints for the CSS file
return new Response(HTML, {
headers: {
"content-type": "text/html",
link: "</test.css>; rel=preload; as=style",
},
});
}
},
} satisfies ExportedHandler;
103 Early Hints overview and purpose
103 Early Hints is an HTTP status code designed to speed up content delivery. When enabled, Cloudflare caches the Link headers marked with preload and/or preconnect from HTML pages and serves them in a 103 Early Hints response before reaching the origin server. Browsers can use these hints to fetch linked assets while waiting for the origin's final response, dramatically improving page load speeds.
Early Hints Python implementation example
Example of implementing Early Hints in a Cloudflare Worker using Python:
import re
from workers import Response, WorkerEntrypoint
CSS = "body { color: red; }"
HTML = """
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Early Hints test</title>
<link rel="stylesheet" href="/test.css">
</head>
<body>
<h1>Early Hints test page</h1>
</body>
</html>
"""
class Default(WorkerEntrypoint):
async def fetch(self, request):
if re.search("test.css", request.url):
headers = {"content-type": "text/css"}
return Response(CSS, headers=headers)
else:
headers = {"content-type": "text/html","link": "</test.css>; rel=preload; as=style"}
return Response(HTML, headers=headers)
Implement optimistic sync guard for game state
When sending game moves to the server, include the expected FEN position from the client side. The server can compare this against its current board state to detect staleness and reject moves made on outdated board states.
useAgent hook for React integration
Use the useAgent hook from agents/react library to connect React components to a Durable Object. Pass an object with host, name (agent instance identifier), agent class name, and onStateUpdate callback. The hook returns a stub object with methods matching the @callable decorated methods.
Send follow-up messages from app to ChatGPT
Call window.openai?.sendFollowUpMessage?() with a prompt object to send a new message to the ChatGPT conversation. This enables bidirectional communication where the app can prompt ChatGPT with contextual information.
Optimize application by storing playerId in localStorage
Use localStorage to persist a player's ID across sessions. Generate a UUID via crypto.randomUUID() if no existing playerId is found, store it, and retrieve it on subsequent loads to maintain player continuity.
Use @callable decorator to expose Durable Object methods
Use the @callable() decorator on Durable Object methods to expose them for client invocation. These decorated methods can be called from the React UI or other clients connected to the agent.
Aggregate requests example - TypeScript
Example showing how to send two GET requests concurrently and aggregate the responses using TypeScript. Uses Promise.all() to fetch two URLs in parallel, parse their JSON responses, and return the aggregated results as a single JSON response. Includes ExportedHandler type annotation.
Code:
```ts
export default {
async fetch(request) {
const someHost = "https://jsonplaceholder.typicode.com";
const url1 = someHost + "/todos/1";
const url2 = someHost + "/todos/2";
const responses = await Promise.all([fetch(url1), fetch(url2)]);
const results = await Promise.all(responses.map((r) => r.json()));
const options = {
headers: { "content-type": "application/json;charset=UTF-8" },
};
return new Response(JSON.stringify(results), options);
},
} satisfies ExportedHandler;
```
Aggregate requests example - Python
Example showing how to send two GET requests concurrently and aggregate the responses using Python Workers. Uses asyncio.gather() to fetch two URLs in parallel, parse their JSON responses, and return the aggregated results using Response.json().
Code:
```py
from workers import Response, fetch, WorkerEntrypoint
import asyncio
import json
class Default(WorkerEntrypoint):
async def fetch(self, request):
some_host = "https://jsonplaceholder.typicode.com"
url1 = some_host + "/todos/1"
url2 = some_host + "/todos/2"
responses = await asyncio.gather(fetch(url1), fetch(url2))
results = await asyncio.gather(*(r.json() for r in responses))
headers = {"content-type": "application/json;charset=UTF-8"}
return Response.json(results, headers=headers)
```
Aggregate requests example - Hono
Example showing how to send two GET requests concurrently and aggregate the responses using the Hono framework. Uses Promise.all() to fetch two URLs in parallel, parse their JSON responses, and return the aggregated results using Hono's c.json() method.
Code:
```ts
import { Hono } from "hono";
const app = new Hono();
app.get("*", async (c) => {
const someHost = "https://jsonplaceholder.typicode.com";
const url1 = someHost + "/todos/1";
const url2 = someHost + "/todos/2";
const responses = await Promise.all([fetch(url1), fetch(url2)]);
const results = await Promise.all(responses.map((r) => r.json()));
return c.json(results);
});
export default app;
```
A/B testing TypeScript implementation
This example shows a complete A/B testing worker in TypeScript with ExportedHandler type:
```ts
const NAME = "myExampleWorkersABTest";
export default {
async fetch(req): Promise<Response> {
const url = new URL(req.url);
// Enable Passthrough to allow direct access to control and test routes.
if (url.pathname.startsWith("/control") || url.pathname.startsWith("/test"))
return fetch(req);
// Determine which group this requester is in.
const cookie = req.headers.get("cookie");
if (cookie && cookie.includes(`${NAME}=control`)) {
url.pathname = "/control" + url.pathname;
} else if (cookie && cookie.includes(`${NAME}=test`)) {
url.pathname = "/test" + url.pathname;
} else {
// If there is no cookie, this is a new client. Choose a group and set the cookie.
const group = Math.random() < 0.5 ? "test" : "control"; // 50/50 split
if (group === "control") {
url.pathname = "/control" + url.pathname;
} else {
url.pathname = "/test" + url.pathname;
}
// Reconstruct response to avoid immutability
let res = await fetch(url);
res = new Response(res.body, res);
// Set cookie to enable persistent A/B sessions.
res.headers.append("Set-Cookie", `${NAME}=${group}; path=/`);
return res;
}
return fetch(url);
},
} satisfies ExportedHandler;
```
The implementation is identical to JavaScript but includes TypeScript type annotations and uses the satisfies keyword with ExportedHandler.
A/B testing JavaScript implementation
This example shows a complete A/B testing worker in JavaScript:
```js
const NAME = "myExampleWorkersABTest";
export default {
async fetch(req) {
const url = new URL(req.url);
// Enable Passthrough to allow direct access to control and test routes.
if (url.pathname.startsWith("/control") || url.pathname.startsWith("/test"))
return fetch(req);
// Determine which group this requester is in.
const cookie = req.headers.get("cookie");
if (cookie && cookie.includes(`${NAME}=control`)) {
url.pathname = "/control" + url.pathname;
} else if (cookie && cookie.includes(`${NAME}=test`)) {
url.pathname = "/test" + url.pathname;
} else {
// If there is no cookie, this is a new client. Choose a group and set the cookie.
const group = Math.random() < 0.5 ? "test" : "control"; // 50/50 split
if (group === "control") {
url.pathname = "/control" + url.pathname;
} else {
url.pathname = "/test" + url.pathname;
}
// Reconstruct response to avoid immutability
let res = await fetch(url);
res = new Response(res.body, res);
// Set cookie to enable persistent A/B sessions.
res.headers.append("Set-Cookie", `${NAME}=${group}; path=/`);
return res;
}
return fetch(url);
},
};
```
The example implements A/B testing by checking the cookie for an existing group assignment, randomly assigning new clients to control or test groups, and persisting the assignment with a Set-Cookie header.
A/B testing Python implementation
This example shows a complete A/B testing worker in Python using Workers WorkerEntrypoint:
```py
import random
from urllib.parse import urlparse, urlunparse
from workers import Response, fetch, WorkerEntrypoint
NAME = "myExampleWorkersABTest"
class Default(WorkerEntrypoint):
async def fetch(self, request):
url = urlparse(request.url)
# Uncomment below when testing locally
# url = url._replace(netloc="example.com") if "localhost" in url.netloc else url
# Enable Passthrough to allow direct access to control and test routes.
if url.path.startswith("/control") or url.path.startswith("/test"):
return fetch(urlunparse(url))
# Determine which group this requester is in.
cookie = request.headers.get("cookie")
if cookie and f'{NAME}=control' in cookie:
url = url._replace(path="/control" + url.path)
elif cookie and f'{NAME}=test' in cookie:
url = url._replace(path="/test" + url.path)
else:
# If there is no cookie, this is a new client. Choose a group and set the cookie.
group = "test" if random.random() < 0.5 else "control"
if group == "control":
url = url._replace(path="/control" + url.path)
else:
url = url._replace(path="/test" + url.path)
# Reconstruct response to avoid immutability
res = await fetch(urlunparse(url))
headers = dict(res.headers)
headers["Set-Cookie"] = f'{NAME}={group}; path=/'
return Response(res.body, headers=headers)
return fetch(urlunparse(url))
```
The Python implementation uses urlparse and urlunparse for URL manipulation and extends WorkerEntrypoint.
A/B testing with cookies and pathname routing
A/B testing can be implemented in a Worker by reading a cookie to determine which variant group a user belongs to, then routing their request to different paths (/control or /test). New clients without the cookie are randomly assigned to a group with a 50/50 split, and the assignment is persisted via a Set-Cookie header. Direct access to /control and /test paths bypasses the A/B logic to allow passthrough requests to the origin.
A/B testing Hono framework implementation
This example shows a complete A/B testing worker using the Hono framework:
```ts
import { Hono } from "hono";
import { getCookie, setCookie } from "hono/cookie";
const app = new Hono();
const NAME = "myExampleWorkersABTest";
// Enable passthrough to allow direct access to control and test routes
app.all("/control/*", (c) => fetch(c.req.raw));
app.all("/test/*", (c) => fetch(c.req.raw));
// Middleware to handle A/B testing logic
app.use("*", async (c) => {
const url = new URL(c.req.url);
// Determine which group this requester is in
const abTestCookie = getCookie(c, NAME);
if (abTestCookie === "control") {
// User is in control group
url.pathname = "/control" + c.req.path;
} else if (abTestCookie === "test") {
// User is in test group
url.pathname = "/test" + c.req.path;
} else {
// If there is no cookie, this is a new client
// Choose a group and set the cookie (50/50 split)
const group = Math.random() < 0.5 ? "test" : "control";
// Update URL path based on assigned group
if (group === "control") {
url.pathname = "/control" + c.req.path;
} else {
url.pathname = "/test" + c.req.path;
}
// Set cookie to enable persistent A/B sessions
setCookie(c, NAME, group, {
path: "/",
});
}
const res = await fetch(url);
return c.body(res.body, res);
});
export default app;
```
The Hono implementation uses the framework's getCookie and setCookie helpers, and defines passthrough routes for direct access.
Python example: modifying response headers
from workers import Response, fetch, WorkerEntrypoint
class Default(WorkerEntrypoint):
async def fetch(self, request):
response = await fetch("https://example.com")
new_headers = response.headers
new_headers["x-workers-hello"] = "Hello from Cloudflare Workers"
if "x-header-to-delete" in new_headers:
del new_headers["x-header-to-delete"]
if "x-header2-to-delete" in new_headers:
del new_headers["x-header2-to-delete"]
new_headers["x-header-to-change"] = "NewValue"
return Response(response.body, headers=new_headers)
JavaScript example: modifying response headers
export default {
async fetch(request) {
const response = await fetch("https://example.com");
const newResponse = new Response(response.body, response);
newResponse.headers.append("x-workers-hello", "Hello from Cloudflare Workers");
newResponse.headers.delete("x-header-to-delete");
newResponse.headers.delete("x-header2-to-delete");
newResponse.headers.set("x-header-to-change", "NewValue");
return newResponse;
}
};
TypeScript example: modifying response headers
export default {
async fetch(request): Promise<Response> {
const response = await fetch(request);
const newResponse = new Response(response.body, response);
newResponse.headers.append("x-workers-hello", "Hello from Cloudflare Workers");
newResponse.headers.delete("x-header-to-delete");
newResponse.headers.delete("x-header2-to-delete");
newResponse.headers.set("x-header-to-change", "NewValue");
return newResponse;
}
} satisfies ExportedHandler;
Hono middleware example: modifying response headers
import { Hono } from 'hono';
const app = new Hono();
app.use('*', async (c, next) => {
await next();
c.res.headers.append("x-workers-hello", "Hello from Cloudflare Workers with Hono");
c.res.headers.delete("x-header-to-delete");
c.res.headers.delete("x-header2-to-delete");
c.res.headers.set("x-header-to-change", "NewValue");
});
app.get('*', async (c) => {
const response = await fetch("https://example.com");
return new Response(response.body, {
headers: response.headers
});
});
export default app;
Hono basicAuth middleware for Basic Authentication
Hono provides a built-in basicAuth middleware that simplifies implementing HTTP Basic Authentication. It takes username and password from environment bindings and automatically handles the authorization flow, including prompting for credentials and validating them.
Request hostname rewriting for origin proxy
To proxy a request to a different origin, create a new URL object from the request URL, check if the incoming hostname matches a configured origin key, and if so, reassign the URL's hostname property to the target origin before fetching the modified URL.
Bulk origin override example - Hono framework
Example showing how to proxy requests from subdomains to different third-party origins using the Hono framework. The code defines an ORIGINS object mapping incoming hostnames to target origins, registers a catch-all route handler with app.all('*'), checks if the request hostname matches a key in ORIGINS, and if so, rewrites the URL hostname and uses the hono/proxy proxy() function to proxy the request to the target origin.
Bulk origin override example - Python
Example showing how to proxy requests from subdomains to different third-party origins using Python. The code defines a Default class that extends WorkerEntrypoint, implements an async fetch() method that defines an ORIGINS dict mapping incoming hostnames to target origins, checks if the request hostname matches a key in ORIGINS, and if so, rewrites the URL hostname and proxies the request using fetch().
Bulk origin override example - TypeScript
Example showing how to proxy requests from subdomains to different third-party origins using TypeScript. The code defines an ORIGINS object mapping incoming hostnames to target origins, checks if the request hostname matches a key in ORIGINS, and if so, rewrites the URL hostname and proxies the request to the target origin using fetch(). The handler satisfies ExportedHandler type.
Hono framework cache helper usage
The Hono framework provides a built-in cache helper that can be used as middleware: app.get('*', cache({ cacheName: 'my-cache', cacheControl: 'max-age=3600' })). This automatically handles caching of responses with the specified cache name and cache control settings.
Response constructor must be used to inherit all response fields
When caching a response from fetch(), use the Response constructor to create a new Response object: new Response(response.body, response). This ensures all response fields (headers, status, etc.) are properly inherited before modifying headers or caching.
Hono bulk redirect middleware example
```ts
import { Hono } from "hono";
const app = new Hono();
const externalHostname = "examples.cloudflareworkers.com";
const redirectMap = new Map([
["/bulk1", `https://${externalHostname}/redirect2`],
["/bulk2", `https://${externalHostname}/redirect3`],
["/bulk3", `https://${externalHostname}/redirect4`],
["/bulk4", "https://google.com"],
]);
app.use("*", async (c, next) => {
const path = c.req.path;
const location = redirectMap.get(path);
if (location) {
return c.redirect(location, 301);
}
await next();
});
app.all("*", async (c) => {
return fetch(c.req.raw);
});
export default app;
```
This example demonstrates implementing bulk redirects using the Hono framework with middleware pattern.
Python bulk redirect example
```py
from workers import WorkerEntrypoint, Response, fetch
from urllib.parse import urlparse
class Default(WorkerEntrypoint):
async def fetch(self, request):
external_hostname = "examples.cloudflareworkers.com"
redirect_map = {
"/bulk1": "https://" + external_hostname + "/redirect2",
"/bulk2": "https://" + external_hostname + "/redirect3",
"/bulk3": "https://" + external_hostname + "/redirect4",
"/bulk4": "https://google.com",
}
url = urlparse(request.url)
location = redirect_map.get(url.path, None)
if location:
return Response.redirect(location, 301)
return fetch(request)
```
This example demonstrates redirecting requests based on a mapped set of paths using Python.
TypeScript bulk redirect example
```ts
export default {
async fetch(request): Promise<Response> {
const externalHostname = "examples.cloudflareworkers.com";
const redirectMap = new Map([
["/bulk1", "https://" + externalHostname + "/redirect2"],
["/bulk2", "https://" + externalHostname + "/redirect3"],
["/bulk3", "https://" + externalHostname + "/redirect4"],
["/bulk4", "https://google.com"],
]);
const requestURL = new URL(request.url);
const path = requestURL.pathname;
const location = redirectMap.get(path);
if (location) {
return Response.redirect(location, 301);
}
return fetch(request);
},
} satisfies ExportedHandler;
```
This example demonstrates redirecting requests based on a mapped set of paths using TypeScript with ExportedHandler type.
JavaScript bulk redirect example
```js
export default {
async fetch(request) {
const externalHostname = "examples.cloudflareworkers.com";
const redirectMap = new Map([
["/bulk1", "https://" + externalHostname + "/redirect2"],
["/bulk2", "https://" + externalHostname + "/redirect3"],
["/bulk3", "https://" + externalHostname + "/redirect4"],
["/bulk4", "https://google.com"],
]);
const requestURL = new URL(request.url);
const path = requestURL.pathname;
const location = redirectMap.get(path);
if (location) {
return Response.redirect(location, 301);
}
return fetch(request);
},
};
```
This example demonstrates redirecting requests based on a mapped set of paths using JavaScript.
Bulk redirects with Map lookup pattern
A common pattern for handling bulk redirects is to define a Map with request paths as keys and destination URLs as values, extract the request pathname, look up the destination in the map, and return Response.redirect() with a 301 status code for matches. Requests not in the map are passed through to the origin via fetch(request).
Conditional response example - block by file extension
To block requests based on file extension, use a regular expression to test the URL pathname. Example: const forbiddenExtRegExp = new RegExp(/\.(doc|xml)$/); if (forbiddenExtRegExp.test(url.pathname)) { return new Response("Blocked Extension", { status: 403 }); }
Conditional response example - redirect by device type
To redirect requests based on device type, retrieve the CF-Device-Type header and use Response.redirect() for conditional redirects. Example: const device = request.headers.get("CF-Device-Type"); if (device === "mobile") { return Response.redirect("https://mobile.example.com"); }
Conditional response example - block by User Agent
To block requests based on User Agent header, retrieve it from request headers and test its contents. Example: const userAgent = request.headers.get("User-Agent") || ""; if (userAgent.includes("bot")) { return new Response("Block User Agent containing bot", { status: 403 }); }
Conditional response example - different response by HTTP method
To return different responses based on HTTP method, check the request.method property. Example: if (request.method === "POST") { return new Response("Response for POST"); }
Conditional response example - block by ASN
To block requests from a specific ASN, access the request.cf.asn property and compare it. Example: if (request.cf && request.cf.asn == 64512) { return new Response("Block the ASN 64512 response"); }
Conditional response example - block by hostname
To block requests based on hostname, create an array of blocked hostnames and check if the incoming request's URL hostname is in that list. Return a 403 response if blocked. Example: const BLOCKED_HOSTNAMES = ["nope.mywebsite.com", "bye.website.com"]; const url = new URL(request.url); if (BLOCKED_HOSTNAMES.includes(url.hostname)) { return new Response("Blocked Host", { status: 403 }); }
Conditional response example - block by client IP
To block requests from a specific IP address, retrieve the CF-Connecting-IP header and compare it. Example: const clientIP = request.headers.get("CF-Connecting-IP"); if (clientIP === "1.2.3.4") { return new Response("Block the IP 1.2.3.4", { status: 403 }); }
Country code redirect example in TypeScript
A TypeScript Worker example that redirects requests based on the country code from request.cf.country. The example defines a countryMap object with country codes (US, EU) as keys and redirect URLs as values. It checks if country is not null and exists in the map, then returns Response.redirect(url). Otherwise, it fetches the request to the default URL.
Country code redirect example in JavaScript
A JavaScript Worker example that redirects requests based on the country code from request.cf.country. The example defines a countryMap object with country codes as keys and redirect URLs as values. If the country matches an entry in the map, it calls Response.redirect(url). Otherwise, it fetches the default URL https://example.com.
Country code redirect example in Python
A Python Worker example using WorkerEntrypoint that redirects requests based on the country code from request.cf.country. It defines a countries dictionary mapping country codes to URLs. If the country matches, it returns Response.redirect(url). Otherwise, it fetches https://example.com.
Country code redirect example in Hono
A Hono framework example that redirects requests based on the country code from request.cf.country. It defines a countryMap object and casts the raw request to include Cloudflare-specific properties. If the country matches the map, it uses c.redirect(url). Otherwise, it fetches the default URL https://example.com.
CORS header proxy example - TypeScript
CORS header proxy implementation in TypeScript with ExportedHandler type. Structure identical to JavaScript version with async fetch(request): Promise<Response> signature. Handles request rewriting to target API URL, sets Origin header to API's origin, fetches response, recreates response to modify headers, sets Access-Control-Allow-Origin to client origin, appends Vary: Origin header. Preflight handling checks for Origin, Access-Control-Request-Method, and Access-Control-Request-Headers headers. Returns CORS headers with methods GET,HEAD,POST,OPTIONS and max-age 86400. Returns 405 for unsupported methods. Includes interactive demo page with tests for proxy and preflight scenarios.
CORS header proxy example - Hono framework
CORS header proxy implementation using Hono framework. Uses app.on() method to handle GET, HEAD, POST, OPTIONS methods on /corsproxy/* route. For OPTIONS preflight requests, checks for Origin, Access-Control-Request-Method, and Access-Control-Request-Headers headers and responds with Access-Control-Allow-Origin: *, Access-Control-Allow-Methods: GET,HEAD,POST,OPTIONS, Access-Control-Max-Age: 86400, and Access-Control-Allow-Headers from request. For actual requests, rewrites to API URL, sets Origin header to API's origin, fetches modified request, recreates response to modify headers, sets Access-Control-Allow-Origin to request origin, and appends Vary: Origin header. Returns 405 for unsupported methods via app.all() fallback. Includes demo page HTML with tests for proxy scenarios.
CORS header proxy example - JavaScript
CORS header proxy implementation in JavaScript. The example creates a reverse proxy at /corsproxy/ endpoint that adds CORS headers to third-party API responses. Key pattern: rewrite the request to point to the target API URL, set the Origin header to the API's origin to make it non-cross-site, fetch the response, recreate it to modify headers, set Access-Control-Allow-Origin to the client's origin, and append Vary: Origin header. Handles OPTIONS preflight requests separately by checking for Origin, Access-Control-Request-Method, and Access-Control-Request-Headers, then responding with appropriate CORS headers including Access-Control-Allow-Methods: GET,HEAD,POST,OPTIONS and Access-Control-Max-Age: 86400. Returns 405 Method Not Allowed for unsupported methods. Includes demo HTML page that shows three test cases: direct fetch without proxy (fails), GET with proxy (succeeds), and POST with preflight (succeeds).
CORS header proxy example - Rust
CORS header proxy implementation in Rust using worker crate. Implements #[event(fetch)] handler with async fetch(req: Request, _env: Env, _ctx: Context) -> Result<Response>. Parses query parameters for apiurl. For OPTIONS requests, checks for access-control-request-method, access-control-request-headers, and origin headers (all lowercase in the actual check), then responds with CORS headers. For GET, HEAD, POST methods, clones request as mutable, sets path to target API URL, sets Origin header to API's origin using url::Origin::Tuple, fetches request, recreates response headers, sets Access-Control-Allow-Origin to client origin, and sets Vary: Origin header. Returns 405 for unsupported methods. CORS headers include methods GET,HEAD,POST,OPTIONS and max-age 86400. Includes demo HTML page.
CORS header proxy example - Python
CORS header proxy implementation in Python using WorkerEntrypoint. Extends WorkerEntrypoint class with async fetch(self, request) method. Parses URL and query parameters to get target API URL. Handles OPTIONS requests by checking for Origin, Access-Control-Request-Method, and Access-Control-Request-Headers headers, responding with CORS headers. For other methods (GET, HEAD, POST), creates new Request with target URL, sets Origin header to target's origin, fetches response, recreates Response object to modify headers, sets Access-Control-Allow-Origin to client origin, and appends Vary: Origin header. Returns 405 for unsupported methods. CORS headers include methods GET,HEAD,POST,OPTIONS and max-age 86400. Includes demo HTML page with test scenarios.
Data loss prevention example with multiple languages
This example is provided in JavaScript, TypeScript, Python, and Hono framework versions, demonstrating how to implement data loss prevention in Cloudflare Workers across different programming languages and frameworks.
Extract cookie value from request headers
To extract a cookie value from incoming requests, parse the Cookie header. In JavaScript, use the 'cookie' npm package's parse function: parse(request.headers.get("Cookie") || ""). This returns an object where you can access cookies by name. In Python, use SimpleCookie from http.cookies and access request.headers["Cookie"]. In Hono, use the getCookie helper function.
JavaScript cookie parsing example
import { parse } from "cookie";
export default {
async fetch(request) {
const COOKIE_NAME = "__uid";
const cookie = parse(request.headers.get("Cookie") || "");
if (cookie[COOKIE_NAME] != null) {
return new Response(cookie[COOKIE_NAME]);
}
return new Response("No cookie with name: " + COOKIE_NAME);
},
};
TypeScript cookie parsing example
import { parse } from "cookie";
export default {
async fetch(request): Promise<Response> {
const COOKIE_NAME = "__uid";
const cookie = parse(request.headers.get("Cookie") || "");
if (cookie[COOKIE_NAME] != null) {
return new Response(cookie[COOKIE_NAME]);
}
return new Response("No cookie with name: " + COOKIE_NAME);
},
} satisfies ExportedHandler;
Python cookie parsing example
from http.cookies import SimpleCookie
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
cookie_name = "__uid"
cookies = SimpleCookie(request.headers["Cookie"] or "")
if cookie_name in cookies:
return Response(cookies[cookie_name].value)
return Response("No cookie with name: " + cookie_name)