Skip to content

Fetch Remote Data ​

Goal: pull third-party API data with LFHttp and render it — a live USD exchange-rate panel.

main.js

js
// ==UserScript==
// @name USD Rate Panel
// @description Show live USD exchange rates on the page
// @match https://example.com/*
// @require dom
// @require http
// ==/UserScript==

LFDOM.ready(async () => {
  const panel = LFDOM.createFloatingRoot({ id: "usd-rates" });
  panel.innerHTML = "<div style='padding:10px 14px'>Loading...</div>";
  try {
    const data = await LFHttp.json("https://open.er-api.com/v6/latest/USD");
    panel.firstElementChild.textContent = `1 USD = ${data.rates.CNY} CNY`;
  } catch (error) {
    panel.firstElementChild.textContent = `Failed to load: ${error.message}`;
  }
});

Why not plain fetch? ​

In-page fetch is constrained by the host site's CSP and CORS. LFHttp routes through the extension background, bypassing those limits with clear guardrails:

  • Rejects the local PluginX client port (41720 on any loopback form; use LFHttp.client), chrome-extension://, file://, and non-http(s) targets (the address after a redirect is checked too)
  • Attaches the target domain's existing browser cookies by default (pass credentials: 'omit' to disable); browser-reserved headers such as Cookie / Referer / User-Agent can be set explicitly via headers and are written on the wire (a Cookie header replaces the browser's own cookies)
  • Object bodies are JSON.stringify'd, but Content-Type is not set for you — add headers: { "content-type": "application/json" } when sending JSON
  • Supports stream() for streaming responses and websocket() for long-lived connections
  • For a timeout or mid-flight cancel, pass signal (e.g. signal: AbortSignal.timeout(10000)): the request is really cancelled and rejects with an AbortError whose code is 'ABORTED' (the browser throttles AbortSignal.timeout in hidden tabs, so it may fire seconds late)

Note

Failed requests throw: non-2xx throws HTTPError, network faults such as DNS failure or a refused connection throw NetworkError, and addresses rejected by policy throw LFHttpUrlBlocked. Wrap calls in try/catch so one failure does not kill the whole app.