Реализация интеграции браузерного расширения с REST API сервера
Браузерное расширение взаимодействует с вашим сервером через REST API: синхронизирует данные, сохраняет настройки, получает обновления конфигурации. Специфика расширений — строгая политика CSP, работа в изолированном контексте и ограничения Manifest V3.
Архитектура коммуникации
Extension (content script)
↓ chrome.runtime.sendMessage
Extension (background service worker)
↓ fetch() → REST API
Server Backend
↓ JSON Response
Background service worker
↓ chrome.runtime.sendResponse
Content script
Background Service Worker (Manifest V3)
// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'save_item') {
saveItemToServer(message.data)
.then(result => sendResponse({ success: true, data: result }))
.catch(err => sendResponse({ success: false, error: err.message }));
return true; // async response
}
});
async function saveItemToServer(itemData) {
const token = await getStoredToken();
const resp = await fetch('https://api.example.com/v1/items', {
method: 'POST',
headers: {
'Content-Type': 'Authorization: Bearer ' + token,
'Authorization': 'Bearer ' + token,
'X-Extension-Version': chrome.runtime.getManifest().version,
},
body: JSON.stringify(itemData),
});
if (!resp.ok) {
if (resp.status === 401) await refreshToken();
throw new Error(`API error: ${resp.status}`);
}
return resp.json();
}
CORS на сервере
// Разрешаем запросы от расширения
// Origin расширения имеет формат: chrome-extension://EXTENSION_ID
class CorsMiddleware
{
public function handle(Request $request, Closure $next): Response
{
$origin = $request->header('Origin');
$allowedOrigins = [
'https://app.example.com',
'chrome-extension://' . config('services.extension.chrome_id'),
'moz-extension://' . config('services.extension.firefox_id'),
];
if (in_array($origin, $allowedOrigins)) {
return $next($request)->header('Access-Control-Allow-Origin', $origin);
}
return $next($request);
}
}
Синхронизация настроек через chrome.storage.sync
// Синхронизация настроек с сервером и chrome.storage.sync
async function syncSettings() {
// Загружаем с сервера
const serverSettings = await apiRequest('GET', '/v1/user/settings');
// Сохраняем локально
await chrome.storage.sync.set({ settings: serverSettings });
return serverSettings;
}
// При изменении настроек — сохраняем на сервер
chrome.storage.sync.onChanged.addListener(async (changes) => {
if (changes.settings) {
await apiRequest('PUT', '/v1/user/settings', changes.settings.newValue);
}
});
Обработка оффлайн-режима
const PENDING_ACTIONS_KEY = 'pending_actions';
async function executeOrQueue(action) {
try {
await fetch(action.url, action.options);
} catch (error) {
// Нет соединения — ставим в очередь
const pending = (await chrome.storage.local.get(PENDING_ACTIONS_KEY))[PENDING_ACTIONS_KEY] || [];
pending.push({ ...action, queued_at: Date.now() });
await chrome.storage.local.set({ [PENDING_ACTIONS_KEY]: pending });
}
}
// Выполняем накопленные действия при восстановлении соединения
chrome.runtime.onStartup.addListener(flushPendingActions);
Сроки
REST API-интеграция расширения с синхронизацией и оффлайн-поддержкой: 4–6 рабочих дней.







