Difference Between serverFetch and browserFetch in Ego-Lite HTTP Module

The difference between serverFetch and browserFetch is that serverFetch executes HTTP requests in the Node.js runtime with a forced browser-like User-Agent, while browserFetch executes requests inside the active browser page via Chrome DevTools Protocol (CDP), inheriting the page's cookies, authentication state, and relative URL resolution.

The Ego-Lite browser automation framework provides two complementary HTTP helpers in its ego-browser package that serve distinct execution contexts. Understanding the difference between serverFetch and browserFetch is essential for choosing the right tool for server-side data extraction versus browser-context API interactions. Both functions are implemented in src/http.ts and offer identical interfaces but operate through fundamentally different networking stacks.

Execution Environment and Context

The primary distinction lies in where the HTTP request physically executes.

serverFetch (Node.js Runtime)

serverFetch runs directly inside the Node.js process hosting the Ego-Lite harness. According to the source code in src/http.ts (lines 11-27), this helper retrieves the native fetch implementation from globalThis and invokes it from the server side. Because it bypasses the browser entirely, it requires absolute URLs and cannot access cookies or session state from the active page.

browserFetch (Browser Page Context)

browserFetch executes within the current browser page that the harness is driving. As implemented in src/http.ts (lines 35-52), this function packages the request parameters into a JSON payload and uses the evaluate() helper from src/cdp-eval.ts to run an async IIFE inside the page context. The request utilizes the browser's native fetch API, inheriting all automatic behaviors including CORS handling, cookie transmission, and authentication headers.

Key Implementation Differences

Beyond execution context, these helpers diverge in four critical areas:

  • User-Agent Handling: serverFetch explicitly forces a browser-like User-Agent header ("Mozilla/5.0") to ensure remote services treat the request as a standard web browser. browserFetch makes no such override, allowing the request to use the page's native user-agent string.

  • URL Resolution: serverFetch accepts absolute URLs only and fails with relative paths. browserFetch accepts relative URLs, resolving them against the active page's location before transmission.

  • Timeout Mechanism: serverFetch uses AbortSignal.timeout for request cancellation, while browserFetch instantiates an AbortController inside the evaluated page script to manage timeouts.

  • Error Handling: Both methods throw custom errors when response.ok is false, but browserFetch propagates exceptions from the browser context back to the Node.js harness through the CDP evaluation layer.

Practical Code Examples

Using serverFetch for Absolute URLs

Use serverFetch when you need to bypass the browser's sandbox or require a consistent user-agent across environments:

import { serverFetch } from 'ego-browser/src/http.js';

const html = await serverFetch('https://api.example.com/data.json', {
  method: 'GET',
  timeout: 10,  // seconds
  headers: { 
    'Accept': 'application/json',
    'Authorization': 'Bearer token123'
  },
});

// Returns raw response text; throws if status >= 400
console.log(html);

Using browserFetch for Relative Endpoints

Use browserFetch when interacting with APIs that rely on the page's authentication state or when fetching resources relative to the current URL:

import { browserFetch } from 'ego-browser/src/http.js';

const profileData = await browserFetch('/api/user/profile', {
  method: 'POST',
  body: JSON.stringify({ id: 123 }),
  headers: { 'Content-Type': 'application/json' },
});

// Automatically includes cookies and auth headers from the active page session
console.log(profileData);

When to Use Each Method

Use serverFetch when:

  • The target endpoint requires a specific browser-like User-Agent that differs from the automation browser
  • You need to fetch resources outside the current page's origin without triggering CORS policies
  • The request must complete even if the browser page crashes or navigates

Use browserFetch when:

  • The API endpoint requires cookies or session tokens set by previous page interactions
  • You need to interact with relative URLs (e.g., /api/endpoint vs https://domain.com/api/endpoint)
  • The server implements anti-automation measures that detect requests originating outside the browser context

Summary

  • serverFetch executes in the Node.js runtime, forces a Mozilla User-Agent, requires absolute URLs, and uses globalThis.fetch with AbortSignal.timeout.
  • browserFetch executes inside the active browser page via CDP evaluation, inherits the page's User-Agent and cookies, supports relative URLs, and uses AbortController within the page context.
  • Both functions return response bodies as plain text and throw on non-OK HTTP statuses.
  • Source implementations reside in src/http.ts (lines 11-27 for serverFetch, lines 35-52 for browserFetch), with browserFetch relying on src/cdp-eval.ts for script injection.

Frequently Asked Questions

Can browserFetch access cookies from the current page?

Yes. Because browserFetch executes inside the active browser page via the Chrome DevTools Protocol, it automatically includes all cookies, session storage, and authentication headers associated with the page's current domain. This makes it ideal for authenticated API calls that rely on browser-established sessions.

Does serverFetch support relative URLs?

No. serverFetch operates in the Node.js runtime outside the browser context and therefore lacks a base URL for resolution. It requires fully qualified absolute URLs (e.g., https://example.com/path). Attempting to pass a relative URL will result in a resolution error.

What timeout mechanism does each method use?

serverFetch utilizes Node.js's AbortSignal.timeout to cancel requests that exceed the specified duration. browserFetch instantiates an AbortController inside the evaluated browser script and passes its signal to the page's native fetch call, achieving identical timeout behavior but through the browser's API surface.

How does error handling differ between the two methods?

Both methods follow the same error pattern: they check response.ok and throw a custom error containing the HTTP method and status code if the response indicates failure. However, browserFetch must serialize errors across the CDP boundary from the browser context back to the Node.js harness, while serverFetch throws immediately within the host process.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →