/** * Runs in Ozon's MAIN world so the request has exactly the same origin and * session context as the page. It accepts only Atlas' two fixed, numeric-SKU * routes and returns a small widget-state allowlist; it never exposes cookies, * request headers or arbitrary fetch capability to the isolated script. */ export default defineContentScript({ matches: ['*://www.ozon.ru/*', '*://www.ozon.kz/*', '*://www.ozon.by/*'], world: 'MAIN', runAt: 'document_idle', main() { window.addEventListener('message', (event) => { if (event.source !== window || !isRequest(event.data)) return; void respond(event.data); }); }, }); type Request = { source: 'atlas-collector'; type: 'ozon-page-json.request'; requestId: string; kind: 'modal-aspects' | 'product' | 'product-detail'; sku: string; }; function isRequest(value: unknown): value is Request { if (!value || typeof value !== 'object' || Array.isArray(value)) return false; const data = value as Record; return ( data.source === 'atlas-collector' && data.type === 'ozon-page-json.request' && typeof data.requestId === 'string' && /^[a-zA-Z0-9-]{16,120}$/.test(data.requestId) && (data.kind === 'modal-aspects' || data.kind === 'product' || data.kind === 'product-detail') && typeof data.sku === 'string' && /^\d{4,}$/.test(data.sku) ); } async function respond(request: Request) { try { const pagePath = request.kind === 'modal-aspects' ? `/modal/aspectsNew?product_id=${request.sku}` : request.kind === 'product-detail' ? `/product/${request.sku}/?layout_container=pdpPage2column&layout_page_index=2` : `/product/${request.sku}/`; const response = await fetch( `/api/entrypoint-api.bx/page/json/v2?url=${encodeURIComponent(pagePath)}`, { credentials: 'same-origin' }, ); if (!response.ok) throw new Error(`Ozon 页面状态请求失败(HTTP ${response.status})`); const value = await response.json(); window.postMessage( { source: 'atlas-collector', type: 'ozon-page-json.response', requestId: request.requestId, ok: true, data: allowlistedPageState(value), }, location.origin, ); } catch (error) { window.postMessage( { source: 'atlas-collector', type: 'ozon-page-json.response', requestId: request.requestId, ok: false, error: error instanceof Error ? error.message : 'Ozon 页面状态请求失败', }, location.origin, ); } } function allowlistedPageState(value: unknown) { if (!value || typeof value !== 'object' || Array.isArray(value)) return { widgetStates: {} }; const states = (value as { widgetStates?: unknown }).widgetStates; if (!states || typeof states !== 'object' || Array.isArray(states)) return { widgetStates: {} }; const widgetStates: Record = {}; for (const [name, state] of Object.entries( states as Record, )) { if ( /^web(Aspects|AspectsModal|ProductHeading|Price|Gallery|Description|RichContent|Features|ShortCharacteristics|DetailedCharacteristics|Characteristics)-/.test( name, ) ) { widgetStates[name] = state; } } return { widgetStates }; }