ScramjetServiceWorker is the core component that intercepts all network requests and proxies them through the configured transport. This page explains how it works.
Overview
Service Workers provide a programmable network proxy that runs in the browser. Scramjet leverages this to intercept fetch requests, decode URLs, fetch content, rewrite it, and return the modified response.Service Workers run in a separate context from your web pages. They persist across page loads and can intercept requests from multiple clients (tabs/windows).
Class structure
TheScramjetServiceWorker class is defined in src/worker/index.ts:
Initialization
When the Service Worker starts, it creates aScramjetServiceWorker instance:
- BareClient for transport
- CookieStore for cookie emulation
- Message listeners for client communication
- IndexedDB to load saved cookies
Loading configuration
The Service Worker loads its configuration from IndexedDB:scramjet.fetch() if the config hasn’t been loaded yet. The config contains:
- URL prefix for routing
- Feature flags
- Codec functions for URL encoding/decoding
- File paths for injected scripts
Configuration can be dynamically updated at runtime via messages from the controller. Changes are persisted to IndexedDB.
Request routing
Theroute() method determines if a request should be handled by Scramjet:
- Start with the configured prefix (e.g.,
/scramjet/) - Request the WASM rewriter file
Request handling
Thefetch() method orchestrates the entire proxy flow:
handleFetch() from src/worker/fetch.ts.
Fetch flow
1
Parse query parameters
Extract metadata from the URL’s query string:
2
Decode URL
Convert the proxied URL back to the real destination:
3
Build metadata context
Create the
URLMeta object for rewriters:4
Handle special URLs
Blob and data URLs are handled directly:
5
Process request headers
Rewrite headers for the real request:
6
Dispatch request event
Allow external code to modify the request:
7
Fetch via transport
Use BareClient to make the actual request:
8
Process response
Rewrite headers, handle cookies, and rewrite the body based on content type.
Response handling
ThehandleResponse() function processes the fetched response:
Header rewriting
- Rewrites
Locationheaders for redirects - Processes
Set-Cookieheaders - Removes
Permissions-Policyheaders that might block Scramjet features - Handles CORS headers
Cookie handling
Body rewriting
Based on the request destination, the response body is rewritten:HTML rewriting details
HTML rewriting details
HTML rewriting injects Scramjet’s client scripts into the
<head> and rewrites:- URL attributes (
src,href,action, etc.) - Inline
<script>and<style>tags - Event handler attributes (
onclick, etc.) - Import maps
<base>tags- Meta refresh tags
- CSP meta tags (removed)
JavaScript rewriting details
JavaScript rewriting details
JavaScript is rewritten using an oxc-based WASM rewriter that:
- Wraps function calls to intercept APIs
- Rewrites property accesses
- Injects runtime helpers
- Generates source maps for debugging
- Handles both classic scripts and ES modules
Download interception
When theinterceptDownloads flag is enabled, Scramjet can intercept file downloads:
Message passing
The Service Worker communicates with clients viapostMessage:
Receiving messages
Dispatching messages
Thedispatch() method sends messages and waits for responses:
Cookie emulation
Scramjet emulates cookies using theCookieStore class because:
- Service Workers cannot access
document.cookie - Real cookies would leak the proxy origin
- Cookie attributes (domain, path, etc.) need special handling
- Stored in the Service Worker’s
CookieStoreinstance - Persisted to IndexedDB
- Synced to clients via
postMessage - Added to outgoing requests via the
Cookieheader
Events
The Service Worker dispatches custom events:ScramjetRequestEvent
Fired before making a request, allowing modification:ScramjetHandleResponseEvent
Fired after receiving a response:Best practices
Next steps
URL rewriting
Learn how URLs are encoded, decoded, and rewritten
Configuration
Explore Service Worker configuration options