Master Chrome Extension Communication: From Content Scripts to Background and Popup

This guide explains Chrome's multi‑process architecture, the roles of each extension script (manifest, popup, background, content, injected), and how they communicate via chrome.runtime, chrome.tabs, and window.postMessage, with practical code examples and diagrams.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Master Chrome Extension Communication: From Content Scripts to Background and Popup

Why Chrome Splits Extensions into Multiple Scripts

Chrome uses a multi‑process architecture (browser main process, renderer processes, network process, GPU process, and extension processes) to isolate work, improve stability, and enhance security.

Each process has a clear responsibility: Browser Main Process: orchestrates windows, tabs, downloads, and permission prompts. Renderer Process: renders web pages and runs injected content.js in an isolated world. Network Process: handles all network requests for pages and extensions. GPU Process: renders animations, video, and 3D effects. Extension Process: runs each installed extension in its own sandbox, preventing one extension from crashing another.

Extension File Structure and Roles

A typical Chrome extension contains the following files:

├── manifest.json   # Extension identity and permissions
├── background.js   # Background script (the brain)
├── content.js     # Content script (runs in page's renderer)
├── injected.js    # Script injected into the page context
└── popup.html     # UI shown when the extension icon is clicked

manifest.json – the "ID card"

Defines the extension name, version, required permissions, and which scripts are loaded. Without it the browser will not recognize the extension.

popup.html – the popup UI

Standard HTML page displayed in a small window when the user clicks the extension icon. It can contain inputs, buttons, and result areas.

background.js – the brain

Runs in the extension process, handles long‑running tasks, listens for messages, performs network requests, and manages data. It cannot directly access the page DOM but can communicate with other scripts.

content.js – the "undercover" script

Injected into the page's renderer process; it can manipulate the DOM but runs in an isolated world, separate from the page's own JavaScript.

injected.js – page‑level script

Creates a <script> tag and inserts it into the page so that the code runs in the page's JavaScript context, allowing you to override native APIs such as fetch or XMLHttpRequest.

Communication Mechanisms

Different parts of an extension talk to each other using the following channels:

background ↔ popup : chrome.runtime.sendMessage background ↔ content : chrome.tabs.sendMessage or chrome.runtime.sendMessage content ↔ page script :

window.postMessage

Example: Weather Query Extension

The popup collects a city name and sends a message to background.js. The background script creates a fake weather string and replies. The popup then displays the result.

<!DOCTYPE html>
<html>
  <body>
    <input id="city" placeholder="城市名" />
    <button id="btn">查天气</button>
    <div id="result"></div>
    <script>
      const btn = document.getElementById('btn');
      btn.onclick = function() {
        const city = document.getElementById('city').value;
        chrome.runtime.sendMessage({type: 'getWeather', city}, function(response) {
          const data = response.weather;
          document.getElementById('result').textContent = data || '查询失败';
        });
      };
    </script>
  </body>
</html>
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === 'getWeather') {
    const fakeWeather = `${msg.city}:晴,25°C`;
    sendResponse({weather: fakeWeather});
    // return true if async (e.g., fetch)
  }
});

Injecting Content Scripts

Two ways to load content.js into a page:

Declarative (manifest)

"content_scripts": [
  {
    "matches": ["https://juejin.cn/*"],
    "js": ["content.js"]
  }
]

Chrome automatically injects the script when a matching page loads.

Programmatic (on‑demand)

From background or popup you can call chrome.scripting.executeScript. The request goes to the browser main process, which forwards it via IPC to the target renderer process, where the script runs in an isolated world.

Cross‑Context Communication Example

When injected.js rewrites fetch, it may need rule data stored in the extension process. The flow is:

Injected script intercepts a fetch request and decides it needs a rule.

Injected script posts a message to the content script via window.postMessage.

Content script forwards the request to the background script with chrome.runtime.sendMessage.

Background script returns the rule data through IPC.

Content script sends the data back to the injected script via window.postMessage.

Injected script applies the rule (e.g., mock, block, log).

Key Takeaways

Chrome's multi‑process model isolates extension components for safety and stability. background.js is the central logic hub; it may be dormant in Manifest V3 and wakes on events. content.js runs in the page's renderer, can modify the DOM but not the page's JS variables directly. popup.html provides a quick UI and disappears when closed. injected.js runs in the page context, enabling deep integration such as API mocking.

Use chrome.runtime.sendMessage, chrome.tabs.sendMessage, and window.postMessage to bridge the communication gaps.

Understanding these concepts helps you avoid common pitfalls like "content script cannot access page variables" or "popup cannot call functions in content.js".

Chrome ExtensionMessagingIPCContent ScriptBackground ScriptPopup UIWeb Extension
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.