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;
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.
Fetch HTML from remote server - Hono framework example
To fetch HTML from a remote server using Hono framework, import Hono and create an app instance. Use app.all("*", async (c) => {...}) to handle all routes. Access the raw request via c.req.raw and call fetch with the remote URL and that request. Example: import { Hono } from "hono"; const app = new Hono(); app.all("*", async (c) => { const remote = "https://example.com"; return await fetch(remote, c.req.raw); }); export default app;
Fetch HTML from remote server - Python example
To fetch HTML from a remote server in Python, create a class named Default that extends WorkerEntrypoint and implements an async fetch method. Import fetch from js module and call it with the remote URL and request. Example: from workers import WorkerEntrypoint; from js import fetch; class Default(WorkerEntrypoint): async def fetch(self, request): remote = "https://example.com"; return await fetch(remote, request)
Fetch HTML from remote server - TypeScript example
To fetch HTML from a remote server and serve it, export a default handler with an async fetch method that takes a Request and returns a Promise<Response>. Call fetch with the remote URL and the incoming request. Example: export default { async fetch(request: Request): Promise<Response> { const remote = "https://example.com"; return await fetch(remote, request); } };
Hono framework example: fetch and return JSON
```ts
import { Hono } from 'hono';
type Env = {};
const app = new Hono<{ Bindings: Env }>();
app.get('*', async (c) => {
const url = "https://jsonplaceholder.typicode.com/todos/1";
// gatherResponse returns both content-type & response body as a string
async function gatherResponse(response: Response) {
const { headers } = response;
const contentType = headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return { contentType, result: JSON.stringify(await response.json()) };
}
return { contentType, result: await response.text() };
}
const response = await fetch(url);
const { contentType, result } = await gatherResponse(response);
return new Response(result, {
headers: { "content-type": contentType }
});
});
export default app;```
Python example: fetch and return JSON
```py
from workers import WorkerEntrypoint, Response, fetch
import json
class Default(WorkerEntrypoint):
async def fetch(self, request):
url = "https://jsonplaceholder.typicode.com/todos/1"
# gather_response returns both content-type & response body as a string
async def gather_response(response):
headers = response.headers
content_type = headers["content-type"] or ""
if "application/json" in content_type:
return (content_type, json.dumps(await response.json()))
return (content_type, await response.text())
response = await fetch(url)
content_type, result = await gather_response(response)
headers = {"content-type": content_type}
return Response(result, headers=headers)```
TypeScript example: fetch and return JSON with types
```ts
interface Env {}
export default {
async fetch(request, env, ctx): Promise<Response> {
const url = "https://jsonplaceholder.typicode.com/todos/1";
// gatherResponse returns both content-type & response body as a string
async function gatherResponse(response) {
const { headers } = response;
const contentType = headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return { contentType, result: JSON.stringify(await response.json()) };
}
return { contentType, result: await response.text() };
}
const response = await fetch(url);
const { contentType, result } = await gatherResponse(response);
const options = { headers: { "content-type": contentType } };
return new Response(result, options);
},
} satisfies ExportedHandler<Env>;```
JavaScript example: fetch and return JSON
```js
export default {
async fetch(request, env, ctx) {
const url = "https://jsonplaceholder.typicode.com/todos/1";
// gatherResponse returns both content-type & response body as a string
async function gatherResponse(response) {
const { headers } = response;
const contentType = headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return { contentType, result: JSON.stringify(await response.json()) };
}
return { contentType, result: await response.text() };
}
const response = await fetch(url);
const { contentType, result } = await gatherResponse(response);
const options = { headers: { "content-type": contentType } };
return new Response(result, options);
},
};```
Fetch JSON from external URL in Workers
This example demonstrates how to send a GET request to an external URL and parse the JSON response. The fetch handler uses the fetch API to request data from an external endpoint, checks the content-type header to determine if the response is JSON, and either parses it as JSON or returns it as text before sending it back to the client.
Geolocation custom styling example with request.cf.timezone
Example Worker that personalizes website styling based on user location and local time. Retrieves timezone from request.cf.timezone, converts to localized time using toLocaleString, and selects a CSS gradient background based on the current hour (0-23). Returns styled HTML with current time and timezone displayed.
JavaScript implementation:
```js
export default {
async fetch(request) {
const timezone = request.cf.timezone;
let localized_date = new Date(
new Date().toLocaleString("en-US", { timeZone: timezone }),
);
let hour = localized_date.getHours();
let minutes = localized_date.getMinutes();
// Build CSS gradient and HTML response based on hour
return new Response(html, {
headers: { "content-type": "text/html;charset=UTF-8" },
});
},
};
```
Convert user timezone to localized Date object
To get the current time in a user's timezone, create a Date object from toLocaleString with the timezone parameter: new Date(new Date().toLocaleString('en-US', { timeZone: timezone })). This returns a Date object representing the current moment in the user's local timezone.
Python Workers geolocation example
Example of using geolocation data in a Python Cloudflare Worker:
```py
from workers import WorkerEntrypoint, Response, fetch
class Default(WorkerEntrypoint):
async def fetch(self, request):
endpoint = "https://api.waqi.info/feed/geo:"
token = "" # Use a token from https://aqicn.org/api/
html_style = "body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}"
html_content = "<h1>Weather 🌦</h1>"
latitude = request.cf.latitude
longitude = request.cf.longitude
endpoint += f"{latitude};{longitude}/?token={token}"
response = await fetch(endpoint)
content = await response.json()
html_content += "<p>This is a demo using Workers geolocation data. </p>"
html_content += f"You are located at: {latitude},{longitude}.</p>"
html_content += f"<p>Based off sensor data from <a href='{content['data']['city']['url']}'>{content['data']['city']['name']}</a>:</p>"
html_content += f"<p>The AQI level is: {content['data']['aqi']}.</p>"
html_content += f"<p>The N02 level is: {content['data']['iaqi']['no2']['v']}.</p>"
html_content += f"<p>The O3 level is: {content['data']['iaqi']['o3']['v']}.</p>"
html_content += f"<p>The temperature is: {content['data']['iaqi']['t']['v']}°C.</p>"
html = f"""
<!DOCTYPE html>
<head>
<title>Geolocation: Weather</title>
</head>
<body>
<style>{html_style}</style>
<div id="container">
{html_content}
</div>
</body>
"""
headers = {"content-type": "text/html;charset=UTF-8"}
return Response(html, headers=headers)
```
Hono framework geolocation example
Example of using geolocation data with the Hono framework on Cloudflare Workers:
```ts
import { Hono } from 'hono';
import { html } from 'hono/html';
type Bindings = {};
interface WeatherApiResponse {
data: {
aqi: number;
city: {
name: string;
url: string;
};
iaqi: {
no2?: { v: number };
o3?: { v: number };
t?: { v: number };
};
};
}
const app = new Hono<{ Bindings: Bindings }>();
app.get('*', async (c) => {
let endpoint = "https://api.waqi.info/feed/geo:";
const token = ""; // Use a token from https://aqicn.org/api/
const html_style = `body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}`;
const req = c.req.raw;
const latitude = req.cf?.latitude;
const longitude = req.cf?.longitude;
endpoint += `${latitude};${longitude}/?token=${token}`;
const init = {
headers: {
"content-type": "application/json;charset=UTF-8",
},
};
const response = await fetch(endpoint, init);
const content = await response.json() as WeatherApiResponse;
const weatherContent = html`
<h1>Weather 🌦</h1>
<p>This is a demo using Workers geolocation data.</p>
<p>You are located at: ${latitude},${longitude}.</p>
<p>Based off sensor data from <a href="${content.data.city.url}">${content.data.city.name}</a>:</p>
<p>The AQI level is: ${content.data.aqi}.</p>
<p>The N02 level is: ${content.data.iaqi.no2?.v}.</p>
<p>The O3 level is: ${content.data.iaqi.o3?.v}.</p>
<p>The temperature is: ${content.data.iaqi.t?.v}°C.</p>
`;
const htmlDocument = html`
<!DOCTYPE html>
<head>
<title>Geolocation: Weather</title>
</head>
<body>
<style>${html_style}</style>
<div id="container">
${weatherContent}
</div>
</body>
`;
return c.html(htmlDocument);
});
export default app;
```
Geolocation weather application example
Example showing how to build a weather application using Workers geolocation data. The worker fetches weather data from the WAQI API (https://api.waqi.info/feed/geo:) using coordinates extracted from the request's cf object, then returns an HTML response displaying the user's location and air quality information.
JavaScript implementation:
```js
export default {
async fetch(request) {
let endpoint = "https://api.waqi.info/feed/geo:";
const token = ""; //Use a token from https://aqicn.org/api/
let html_style = `body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}`;
let html_content = "<h1>Weather 🌦</h1>";
const latitude = request.cf.latitude;
const longitude = request.cf.longitude;
endpoint += `${latitude};${longitude}/?token=${token}`;
const init = {
headers: {
"content-type": "application/json;charset=UTF-8",
},
};
const response = await fetch(endpoint, init);
const content = await response.json();
html_content += `<p>This is a demo using Workers geolocation data. </p>`;
html_content += `You are located at: ${latitude},${longitude}.</p>`;
html_content += `<p>Based off sensor data from <a href="${content.data.city.url}">${content.data.city.name}</a>:</p>`;
html_content += `<p>The AQI level is: ${content.data.aqi}.</p>`;
html_content += `<p>The N02 level is: ${content.data.iaqi.no2?.v}.</p>`;
html_content += `<p>The O3 level is: ${content.data.iaqi.o3?.v}.</p>`;
html_content += `<p>The temperature is: ${content.data.iaqi.t?.v}°C.</p>`;
let html = `
<!DOCTYPE html>
<head>
<title>Geolocation: Weather</title>
</head>
<body>
<style>${html_style}</style>
<div id="container">
${html_content}
</div>
</body>`;
return new Response(html, {
headers: {
"content-type": "text/html;charset=UTF-8",
},
});
},
};
```
Hot-link protection Hono framework example
```ts
import { Hono } from 'hono';
const app = new Hono();
// Middleware for hot-link protection
app.use('*', async (c, next) => {
const HOMEPAGE_URL = "https://tutorial.cloudflareworkers.com/";
const PROTECTED_TYPE = "image/";
// Continue to the next handler to get the response
await next();
// If we have a response, check for hotlinking
if (c.res) {
// If it's an image, engage hotlink protection based on the Referer header
const referer = c.req.header("Referer");
const contentType = c.res.headers.get("Content-Type") || "";
if (referer && contentType.startsWith(PROTECTED_TYPE)) {
// If the hostnames don't match, it's a hotlink
if (new URL(referer).hostname !== new URL(c.req.url).hostname) {
// Redirect the user to your website
c.res = c.redirect(HOMEPAGE_URL, 302);
}
}
}
});
// Default route handler that passes through the request to the origin
app.all('*', async (c) => {
// Fetch the original request
return fetch(c.req.raw);
});
export default app;
```
Hono framework implementation of hot-link protection using middleware to intercept and check responses.
Hot-link protection Python example
```py
from workers import WorkerEntrypoint, Response, fetch
from urllib.parse import urlparse
class Default(WorkerEntrypoint):
async def fetch(self, request):
homepage_url = "https://tutorial.cloudflareworkers.com/"
protected_type = "image/"
# Fetch the original request
response = await fetch(request)
# If it's an image, engage hotlink protection based on the referer header
referer = request.headers["Referer"]
content_type = response.headers["Content-Type"] or ""
if referer and content_type.startswith(protected_type):
# If the hostnames don't match, it's a hotlink
if urlparse(referer).hostname != urlparse(request.url).hostname:
# Redirect the user to your website
return Response.redirect(homepage_url, 302)
# Everything is fine, return the response normally
return response
```
Python hot-link protection implementation using WorkerEntrypoint with urlparse for hostname comparison.
Hot-link protection JavaScript example
```js
export default {
async fetch(request) {
const HOMEPAGE_URL = "https://tutorial.cloudflareworkers.com/";
const PROTECTED_TYPE = "image/";
// Fetch the original request
const response = await fetch(request);
// If it's an image, engage hotlink protection based on the
// Referer header.
const referer = request.headers.get("Referer");
const contentType = response.headers.get("Content-Type") || "";
if (referer && contentType.startsWith(PROTECTED_TYPE)) {
// If the hostnames don't match, it's a hotlink
if (new URL(referer).hostname !== new URL(request.url).hostname) {
// Redirect the user to your website
return Response.redirect(HOMEPAGE_URL, 302);
}
}
// Everything is fine, return the response normally.
return response;
},
};
```
JavaScript hot-link protection implementation that checks Referer header and compares hostnames to detect and redirect hotlinks.
Hot-link protection TypeScript example
```ts
export default {
async fetch(request): Promise<Response> {
const HOMEPAGE_URL = "https://tutorial.cloudflareworkers.com/";
const PROTECTED_TYPE = "image/";
// Fetch the original request
const response = await fetch(request);
// If it's an image, engage hotlink protection based on the Referer header.
const referer = request.headers.get("Referer");
const contentType = response.headers.get("Content-Type") || "";
if (referer && contentType.startsWith(PROTECTED_TYPE)) {
// If the hostnames don't match, it's a hotlink
if (new URL(referer).hostname !== new URL(request.url).hostname) {
// Redirect the user to your website
return Response.redirect(HOMEPAGE_URL, 302);
}
}
// Everything is fine, return the response normally.
return response;
},
} satisfies ExportedHandler;
```
TypeScript hot-link protection implementation with response type annotation and ExportedHandler type satisfaction.
Hot-link protection example implementation
Hot-link protection blocks other websites from linking directly to your content by checking the Referer header. The example demonstrates checking if an incoming request is for an image, and if the hostname of the Referer header differs from the requested URL's hostname. If it's a hotlink, redirect the user to your homepage with a 302 status code.
Geolocation Hello World example in Hono
import { Hono } from "hono";
import { html } from "hono/html";
interface RequestWithCf extends Request {
cf: {
colo: string;
country: string;
city: string;
continent: string;
latitude: string;
longitude: string;
postalCode: string;
metroCode: string;
region: string;
regionCode: string;
timezone: string;
};
}
const app = new Hono();
app.get("*", (c) => {
const request = c.req.raw;
const html_style = "body{padding:6em; font-family: sans-serif;} h1{color:#f6821f;}";
let html_content = html` <p>Colo: ${request.cf.colo}</p>
<p>Country: ${request.cf.country}</p>
<p>City: ${request.cf.city}</p>
<p>Continent: ${request.cf.continent}</p>
<p>Latitude: ${request.cf.latitude}</p>
<p>Longitude: ${request.cf.longitude}</p>
<p>PostalCode: ${request.cf.postalCode}</p>
<p>MetroCode: ${request.cf.metroCode}</p>
<p>Region: ${request.cf.region}</p>
<p>RegionCode: ${request.cf.regionCode}</p>
<p>Timezone: ${request.cf.timezone}</p>`;
const htmlContent = html`<!DOCTYPE html>
<head>
<title>Geolocation: Hello World</title>
<style>
${html_style}
</style>
</head>
<body>
<h1>Geolocation: Hello World!</h1>
<p>
You now have access to geolocation data about where your user is
visiting from.
</p>
${html_content}
</body> `;
return c.html(htmlContent);
});
export default app;
Geolocation Hello World example in TypeScript
export default {
async fetch(request): Promise<Response> {
let html_content = "";
let html_style = "body{padding:6em; font-family: sans-serif;} h1{color:#f6821f;}";
html_content += "<p> Colo: " + request.cf.colo + "</p>";
html_content += "<p> Country: " + request.cf.country + "</p>";
html_content += "<p> City: " + request.cf.city + "</p>";
html_content += "<p> Continent: " + request.cf.continent + "</p>";
html_content += "<p> Latitude: " + request.cf.latitude + "</p>";
html_content += "<p> Longitude: " + request.cf.longitude + "</p>";
html_content += "<p> PostalCode: " + request.cf.postalCode + "</p>";
html_content += "<p> MetroCode: " + request.cf.metroCode + "</p>";
html_content += "<p> Region: " + request.cf.region + "</p>";
html_content += "<p> RegionCode: " + request.cf.regionCode + "</p>";
html_content += "<p> Timezone: " + request.cf.timezone + "</p>";
let html = `<!DOCTYPE html>
<head>
<title> Geolocation: Hello World </title>
<style> ${html_style} </style>
</head>
<body>
<h1>Geolocation: Hello World!</h1>
<p>You now have access to geolocation data about where your user is visiting from.</p>
${html_content}
</body>`;
return new Response(html, {
headers: {
"content-type": "text/html;charset=UTF-8",
},
});
},
} satisfies ExportedHandler;
Geolocation Hello World example in Python
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
html_content = ""
html_style = "body{padding:6em font-family: sans-serif;} h1{color:#f6821f;}"
html_content += "<p> Colo: " + request.cf.colo + "</p>"
html_content += "<p> Country: " + request.cf.country + "</p>"
html_content += "<p> City: " + request.cf.city + "</p>"
html_content += "<p> Continent: " + request.cf.continent + "</p>"
html_content += "<p> Latitude: " + request.cf.latitude + "</p>"
html_content += "<p> Longitude: " + request.cf.longitude + "</p>"
html_content += "<p> PostalCode: " + request.cf.postalCode + "</p>"
html_content += "<p> Region: " + request.cf.region + "</p>"
html_content += "<p> RegionCode: " + request.cf.regionCode + "</p>"
html_content += "<p> Timezone: " + request.cf.timezone + "</p>"
html = f"""
<!DOCTYPE html>
<head>
<title> Geolocation: Hello World </title>
<style> {html_style} </style>
</head>
<body>
<h1>Geolocation: Hello World!</h1>
<p>You now have access to geolocation data about where your user is visiting from.</p>
{html_content}
</body>
"""
headers = {"content-type": "text/html;charset=UTF-8"}
return Response(html, headers=headers)
TypeScript example for custom image domain
The following code serves images from a custom domain using TypeScript:
```ts
export default {
async fetch(request): Promise<Response> {
const accountHash = "";
const { pathname } = new URL(request.url);
return fetch(`https://imagedelivery.net/${accountHash}${pathname}`);
},
} satisfies ExportedHandler;
```
Alternative: prefix path for custom image domain
Images can be served from a custom domain using the cdn-cgi/imagedelivery prefix path. The URL format is: https://example.com/cdn-cgi/imagedelivery/<ACCOUNT_HASH>/<IMAGE_ID>/<VARIANT_NAME>. This requires the custom domain to be a Cloudflare proxied domain under the same account as the Image. The account hash, image ID, and variant name can be found in the Images section of the Cloudflare dashboard.
Python example for custom image domain
The following code serves images from a custom domain using Python:
```py
from workers import WorkerEntrypoint
from js import URL, fetch
class Default(WorkerEntrypoint):
async def fetch(self, request):
account_hash = ""
url = URL.new(request.url)
return fetch(f'https://imagedelivery.net/{account_hash}{url.pathname}')
```
Hono example for custom image domain
The following code serves images from a custom domain using the Hono framework:
```ts
import { Hono } from 'hono';
interface Env {
ACCOUNT_HASH?: string;
}
const app = new Hono<{ Bindings: Env }>();
app.get('*', async (c) => {
const accountHash = c.env.ACCOUNT_HASH || "";
const url = new URL(c.req.url);
return fetch(`https://imagedelivery.net/${accountHash}${url.pathname}`);
});
export default app;
```
JavaScript example for custom image domain
The following code serves images from a custom domain by proxying to imagedelivery.net:
```js
export default {
async fetch(request) {
const accountHash = "";
const { pathname } = new URL(request.url);
return fetch(`https://imagedelivery.net/${accountHash}${pathname}`);
},
};
```
A request to cdn.example.com/83eb7b2-5392-4565-b69e-aff66acddd00/public will fetch from https://imagedelivery.net/<accountHash>/83eb7b2-5392-4565-b69e-aff66acddd00/public
Custom domain for Images using Workers
To serve images from a custom domain using a Worker, create a Worker that fetches from imagedelivery.net with your account hash. The Worker extracts the pathname from the incoming request and appends it to the imagedelivery.net URL with your account hash, effectively proxying requests to Cloudflare's image delivery service.
Hono example: logging headers multiple ways
import { Hono } from 'hono';
const app = new Hono();
app.get('*', (c) => {
// Different ways to log headers in Hono:
// 1. Using Map to display headers in console
console.log('Headers as Map:', new Map(c.req.raw.headers));
// 2. Using spread operator to log headers
console.log('Headers spread:', [...c.req.raw.headers]);
// 3. Using Object.fromEntries to convert to an object
console.log('Headers as Object:', Object.fromEntries(c.req.raw.headers));
// 4. Hono's built-in header accessor (for individual headers)
console.log('User-Agent:', c.req.header('User-Agent'));
// 5. Using c.req.headers to get all headers
console.log('All headers from Hono context:', c.req.header());
return c.text('Hello world');
});
export default app;
Python example: logging headers
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
print(dict(request.headers))
return Response('Hello world')
Rust example: logging headers
use worker::*;
#[event(fetch)]
async fn fetch(req: HttpRequest, _env: Env, _ctx: Context) -> Result<Response> {
console_log!("{:?}", req.headers());
Response::ok("hello world")
}
Convert Headers to object with Object.fromEntries
To convert a Headers object to a plain JavaScript object, use Object.fromEntries(request.headers). This allows you to then stringify the object with JSON.stringify(headersObject) for logging or other purposes.
TypeScript example: logging headers with Map
export default {
async fetch(request): Promise<Response> {
console.log(new Map(request.headers));
return new Response("Hello world");
},
} satisfies ExportedHandler;
JavaScript example: logging headers with Map
export default {
async fetch(request) {
console.log(new Map(request.headers));
return new Response("Hello world");
},
};
Headers object appears empty when logged directly
Logging a Headers object directly with console.log(request.headers) or JSON.stringify(request.headers) results in an empty object string '{}' even if headers are present. This occurs because Headers objects do not store headers in enumerable JavaScript properties, making them opaque to console inspection and JSON stringification. However, the headers are actually present and can be accessed with methods like request.headers.has().
Headers object stringification with spread operator
To stringify a Headers object for logging, use the spread operator to convert it to an array before JSON stringification: JSON.stringify([...request.headers]). Do not use JSON.stringify(new Map(request.headers)) because Map uses Symbol-keyed properties which JSON.stringify ignores, resulting in an empty object.
Headers object logging with Map
To log a Headers object to the console, construct a Map object from the Headers object and log the Map. Use console.log(new Map(request.headers)). This works because Map objects can be constructed from iterables like Headers, and Map stores entries in enumerable JavaScript properties visible to the developer console.
Hono with Cron Triggers
A Worker using Hono can handle both regular HTTP requests and Cron Triggers by exporting both a fetch handler (for HTTP) and a scheduled handler (for cron). The example shows exporting {fetch: app.fetch, async scheduled(controller, env, ctx) {...}}.
Stream OpenAI responses with Hono framework
In Hono, use the streamText helper to stream OpenAI responses. Call openai.chat.completions.create with stream: true, then iterate over the chatStream with for await...of, writing each message.choices[0].delta.content to the Hono stream. The streamText function automatically handles backpressure and response formatting.
Stream OpenAI API responses using TransformStream
To stream OpenAI API responses in Cloudflare Workers, create a TransformStream with readable and writable properties. Use ctx.waitUntil to handle the async streaming loop. Get a writer from the writable side, then iterate over the OpenAI stream with for await...of, encoding each delta.content to text and writing to the writable side. Finally, close the writer and return a new Response with the readable side.
POST JSON example with TypeScript
Example of sending a POST request with JSON data in a Cloudflare Worker using TypeScript. The worker constructs a fetch request with JSON-serialized body, sets the content-type header to 'application/json;charset=UTF-8', uses a gatherResponse helper function to parse the response based on its content-type header, and exports a handler that satisfies the ExportedHandler interface.
```ts
export default {
async fetch(request): Promise<Response> {
const someHost = "https://examples.cloudflareworkers.com/demos";
const url = someHost + "/requests/json";
const body = {
results: ["default data to send"],
errors: null,
msg: "I sent this to the fetch",
};
async function gatherResponse(response) {
const { headers } = response;
const contentType = headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return JSON.stringify(await response.json());
} else if (contentType.includes("application/text")) {
return response.text();
} else if (contentType.includes("text/html")) {
return response.text();
} else {
return response.text();
}
}
const init = {
body: JSON.stringify(body),
method: "POST",
headers: {
"content-type": "application/json;charset=UTF-8",
},
};
const response = await fetch(url, init);
const results = await gatherResponse(response);
return new Response(results, init);
},
} satisfies ExportedHandler;
```
POST JSON example with Python
Example of sending a POST request with JSON data in a Cloudflare Worker using Python. The worker uses the json module to serialize the request body, calls fetch with the JSON body and content-type header set to 'application/json;charset=UTF-8', and includes a gather_response function that inspects the content-type header to determine how to parse the response.
```py
import json
from workers import WorkerEntrypoint, Response, fetch
async def gather_response(response):
headers = response.headers
content_type = headers["content-type"] or ""
if "application/json" in content_type:
return (content_type, json.dumps(dict(await response.json())))
return (content_type, await response.text())
class Default(WorkerEntrypoint):
async def fetch(self, _request):
url = "https://jsonplaceholder.typicode.com/todos/1"
body = {
"results": ["default data to send"],
"errors": None,
"msg": "I sent this to the fetch",
}
response = await fetch(
url,
method="POST",
body=json.dumps(body),
headers={"content-type": "application/json;charset=UTF-8"},
)
content_type, result = await gather_response(response)
return Response(result, headers={"content-type": content_type})
```
POST JSON example with Hono framework
Example of sending a POST request with JSON data in a Cloudflare Worker using the Hono framework. The application creates a route that constructs a fetch request with a JSON body, sets the content-type header to 'application/json;charset=UTF-8', uses a gatherResponse function to inspect the response's content-type header and parse accordingly, and returns a Response with the appropriate content-type.
```ts
import { Hono } from 'hono';
const app = new Hono();
app.get('*', async (c) => {
const someHost = "https://examples.cloudflareworkers.com/demos";
const url = someHost + "/requests/json";
const body = {
results: ["default data to send"],
errors: null,
msg: "I sent this to the fetch",
};
async function gatherResponse(response: Response) {
const { headers } = response;
const contentType = headers.get("content-type") || "";
if (contentType.includes("application/json")) {
return { contentType, result: JSON.stringify(await response.json()) };
} else if (contentType.includes("application/text")) {
return { contentType, result: await response.text() };
} else if (contentType.includes("text/html")) {
return { contentType, result: await response.text() };
} else {
return { contentType, result: await response.text() };
}
}
const init = {
body: JSON.stringify(body),
method: "POST",
headers: {
"content-type": "application/json;charset=UTF-8",
},
};
const response = await fetch(url, init);
const { contentType, result } = await gatherResponse(response);
return new Response(result, {
headers: {
"content-type": contentType,
},
});
});
export default app;
```
Parse response by content-type in POST request handler
When handling responses from POST requests, inspect the response's content-type header and parse the response body accordingly. Check if the header includes 'application/json', 'application/text', or 'text/html' to determine whether to call response.json() or response.text().
Python redirect example preserving path and query
from workers import WorkerEntrypoint, Response
from urllib.parse import urlparse
class Default(WorkerEntrypoint):
async def fetch(self, request):
base = "https://example.com"
statusCode = 301
url = urlparse(request.url)
destinationURL = f'{base}{url.path}{url.query}'
print(destinationURL)
return Response.redirect(destinationURL, statusCode)
Rust redirect example preserving path and query
use worker::*;
#[event(fetch)]
async fn fetch(req: Request, _env: Env, _ctx: Context) -> Result<Response> {
let mut base = Url::parse("https://example.com")?;
let status_code = 301;
let url = req.url()?;
base.set_path(url.path());
base.set_query(url.query());
console_log!("{:?}", base.to_string());
Response::redirect_with_status(base, status_code)
}
Hono redirect example preserving path and query
import { Hono } from "hono";
const app = new Hono();
app.all("*", (c) => {
const base = "https://example.com";
const statusCode = 301;
const { pathname, search } = new URL(c.req.url);
const destinationURL = `${base}${pathname}${search}`;
console.log(destinationURL);
return c.redirect(destinationURL, statusCode);
});
export default app;
Hono redirect example for all requests
import { Hono } from "hono";
const app = new Hono();
app.all("*", (c) => {
const destinationURL = "https://example.com";
const statusCode = 301;
return c.redirect(destinationURL, statusCode);
});
export default app;
TypeScript redirect example preserving path and query
export default {
async fetch(request): Promise<Response> {
const base = "https://example.com";
const statusCode = 301;
const url = new URL(request.url);
const { pathname, search } = url;
const destinationURL = `${base}${pathname}${search}`;
console.log(destinationURL);
return Response.redirect(destinationURL, statusCode);
},
} satisfies ExportedHandler;
Redirect requests preserving pathname and query string
To redirect requests from one domain to another while preserving the original pathname and query string, parse the incoming request URL using new URL(request.url), extract the pathname and search properties, and construct the destination URL by combining the base domain with the original pathname and search parameters. This pattern works in JavaScript and TypeScript by building a string like `${base}${pathname}${search}`.
JavaScript redirect example preserving path and query
export default {
async fetch(request) {
const base = "https://example.com";
const statusCode = 301;
const url = new URL(request.url);
const { pathname, search } = url;
const destinationURL = `${base}${pathname}${search}`;
console.log(destinationURL);
return Response.redirect(destinationURL, statusCode);
},
};
Redirect all requests to a single URL with Response.redirect
To redirect all incoming requests to a single destination URL, use Response.redirect(destinationURL, statusCode). The statusCode parameter specifies the HTTP status code for the redirect, typically 301 for permanent redirects. This works across JavaScript, TypeScript, Python, Rust, and Hono frameworks.
ExportedHandler TypeScript interface
TypeScript Workers handlers should satisfy the ExportedHandler interface, which requires an async fetch method that takes a request and returns a Promise<Response>.
Basic fetch proxy pattern in Python
A Workers handler written in Python can forward requests to another website using the fetch() function. The example shows a Python handler that validates the request method is GET, returns a 405 response with an Allow header for other methods, and proxies GET requests to example.com.
Basic fetch proxy pattern in TypeScript
A Workers handler can forward requests to another website by returning the result of fetch(). The example shows a TypeScript handler that only allows GET requests and proxies them to example.com, returning a 405 Method Not Allowed response for other HTTP methods.
TypeScript example: read POST request body with type hints
```ts
async function readRequestBody(request: Request) {
const contentType = request.headers.get('content-type');
if (contentType.includes('application/json')) {
return JSON.stringify(await request.json());
} else if (contentType.includes('application/text')) {
return request.text();
} else if (contentType.includes('text/html')) {
return request.text();
} else if (contentType.includes('form')) {
const formData = await request.formData();
const body = {};
for (const entry of formData.entries()) {
body[entry[0]] = entry[1];
}
return JSON.stringify(body);
} else {
return 'a file';
}
}
```
This example shows typed request body reading for different content types.
Read text from POST request
To read plain text from a POST request, check the content-type header for 'application/text' or 'text/html', then call await request.text().
Read form data from POST request
To read form data from a POST request, check the content-type header for 'form', then call await request.formData(). Iterate through formData.entries() to extract key-value pairs into an object.
Read JSON from POST request
To read JSON from a POST request, check the content-type header for 'application/json', then call await request.json() and JSON.stringify() the result.