0Pricing
Browser Extensions Development (Chrome & Edge) · Урок

Двунаправленный обмен сообщениями между компонентами

Освойте более сложный двунаправленный обмен данными с помощью передачи сообщений для взаимодействия по принципу «запрос — ответ» между частями расширения.

«Двунаправленный обмен сообщениями между компонентами» — бесплатный урок Browser Extensions Development (Chrome & Edge) на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Browser Extensions Development (Chrome & Edge), и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Browser Extensions Development (Chrome & Edge) содержит 4 уроков всего.

Части этого урока еще не переведены и отображаются на английском.

Two-Way Messaging Intro

Welcome! In this lesson, you'll master two-way messaging, a powerful way for different parts of your browser extension to communicate effectively.

Unlike one-way messages, two-way messaging allows a sender to not only send a request but also to receive a specific response back from the receiver.

The Request-Response Model

Two-way communication follows a simple request-response model:

  • A component (e.g., a popup) sends a message (the request).
  • Another component (e.g., the background script) receives and processes it.
  • The receiving component then sends a message back (the response).
  • The original sender receives this response and acts on it.

Sending a Request with Callback

To send a request and expect a response, you use chrome.runtime.sendMessage() with an optional callback function. This callback will execute once the response is received.

Try running this example from a popup or content script:

/* popup.js or content-script.js */
console.log("Sending request to background...");

chrome.runtime.sendMessage({type: "fetchSettings", key: "theme"},
  function(response) {
    if (chrome.runtime.lastError) {
      console.error("Error sending message:", chrome.runtime.lastError.message);
      return;
    }
    if (response && response.status === "success") {
      console.log("Received setting:", response.value);
    } else {
      console.error("Failed to get setting:", response.error);
    }
  }
);

Receiving & Responding (Sync)

The receiving component (often your background service worker) listens for messages using chrome.runtime.onMessage.addListener(). This listener receives the request, sender, and a special sendResponse function.

To send a synchronous response, simply call sendResponse() with your data. The message channel will then close.

/* service-worker.js (background script) */
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log("Background received request:", request.type);

    if (request.type === "fetchSettings") {
      // Simulate fetching a setting synchronously
      const settings = {theme: "dark", notifications: true};
      const value = settings[request.key];

      if (value !== undefined) {
        sendResponse({status: "success", value: value});
      } else {
        sendResponse({status: "error", error: "Setting not found"});
      }
    }
    // No 'return true;' needed for synchronous response
  }
);

Handling Async Responses

What if your response depends on an asynchronous operation, like fetching data from an API or local storage? If you call sendResponse() inside an async callback, the message channel might close before your response is ready.

To prevent this, return true from your onMessage.addListener callback. This tells Chrome to keep the channel open, allowing you to call sendResponse() later.

/* service-worker.js (background script) */
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.type === "fetchAsyncData") {
      console.log("Processing async request...");
      // Simulate an async data fetch
      setTimeout(() => {
        const data = {id: 'unique123', content: 'Fetched after delay'};
        sendResponse({status: "success", data: data});
      }, 500); // Wait 500ms

      return true; // IMPORTANT: Keeps the message channel open
    }
  }
);

Popup to Content Script

You can also establish two-way communication directly between a popup and a content script running on the active tab. For this, the popup uses chrome.tabs.sendMessage(), specifying the tab ID.

The content script then uses chrome.runtime.onMessage.addListener(), just like a background script.

/* popup.js */
console.log("Sending message to active tab...");

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  if (tabs.length > 0) {
    chrome.tabs.sendMessage(tabs[0].id, {action: "getSelection"},
      function(response) {
        if (chrome.runtime.lastError) {
          console.error("Error from content script:", chrome.runtime.lastError.message);
          return;
        }
        if (response && response.selectedText) {
          console.log("Selected text:", response.selectedText);
        } else {
          console.log("No text selected.");
        }
      }
    );
  }
});

Content Script Responds

Here's how the content script on the web page would receive the message from the popup and send back the currently selected text.

Remember, the content script also uses chrome.runtime.onMessage.addListener() and can use sendResponse().

/* content.js */
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log("Content script received action:", request.action);

    if (request.action === "getSelection") {
      const selectedText = window.getSelection().toString();
      sendResponse({selectedText: selectedText});
    }
    // For synchronous response, no 'return true;' is needed
  }
);

Error Handling Tips

Robust error handling is crucial:

  • Check chrome.runtime.lastError: After sendMessage(), always check this property to catch errors like disconnected ports (e.g., if the receiving script isn't active).
  • Include status in response: Design your response objects with a status field (e.g., 'success', 'error') and an optional message or error field for details.
  • Handle undefined responses: The callback might be called with an undefined response if the receiver doesn't call sendResponse().

Best Practices for Two-Way

To ensure smooth and maintainable two-way messaging:

  • Define clear message types: Use a type or action field in your message objects (e.g., {type: "getData"}) to easily identify intent.
  • Keep messages simple: Pass only necessary, JSON-serializable data. Avoid complex objects or DOM elements.
  • Centralize listener logic: If possible, use a single onMessage.addListener in your background script and route requests based on their type.
  • Document message contracts: Clearly define what each message type expects and what response it returns.

Check Your Understanding

Test your knowledge of two-way messaging!

Recap & Next Steps

You've mastered two-way messaging!

  • You learned how to send requests using chrome.runtime.sendMessage() and receive responses via a callback.
  • You can now use chrome.runtime.onMessage.addListener() with sendResponse() to reply to messages, handling both synchronous and asynchronous scenarios.
  • You also saw how to enable communication between popups and content scripts using chrome.tabs.sendMessage().

Next, you'll explore how to persist data using the chrome.storage API, which often works hand-in-hand with messaging!

Часто задаваемые вопросы

Урок «Двунаправленный обмен сообщениями между компонентами» бесплатный?

Да — полный текст урока «Двунаправленный обмен сообщениями между компонентами» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Browser Extensions Development (Chrome & Edge), подпишись на CoddyKit PRO. Курс Browser Extensions Development (Chrome & Edge) содержит 4 уроков всего.

Чему я научусь в уроке «Двунаправленный обмен сообщениями между компонентами»?

Освойте более сложный двунаправленный обмен данными с помощью передачи сообщений для взаимодействия по принципу «запрос — ответ» между частями расширения. Ты практикуешь Browser Extensions Development (Chrome & Edge) с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Browser Extensions Development (Chrome & Edge)?

Предыдущий опыт не требуется. Browser Extensions Development (Chrome & Edge) на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Двунаправленный обмен сообщениями между компонентами»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Browser Extensions Development (Chrome & Edge)?

Да. Каждый урок Browser Extensions Development (Chrome & Edge) включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Односторонние шаблоны обмена сообщениями
  2. Двунаправленный обмен сообщениями между компонентами
  3. Использование API Chrome Storage
  4. Синхронное и локальное хранилища и квоты
← Назад к Browser Extensions Development (Chrome & Edge)