45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
import { uploadMaterials } from '../src/api/client';
|
|
|
|
// Background Service Worker —— 唯一出网口(代理图片 fetch / 上传服务端,绕 CORS / 防盗链)
|
|
export default defineBackground(() => {
|
|
console.log('[套娃采集助手] background started');
|
|
|
|
// 点击扩展图标 → 打开 Side Panel
|
|
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
|
|
|
|
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
|
|
if (msg?.action === 'fetchImage') {
|
|
fetchImageAsDataUrl(msg.url)
|
|
.then((dataUrl) => sendResponse({ ok: true, dataUrl }))
|
|
.catch((err) => sendResponse({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
return true; // 保持异步通道
|
|
}
|
|
|
|
if (msg?.action === 'uploadMaterials') {
|
|
uploadMaterials(msg.baseUrl, msg.token, msg.payload)
|
|
.then((data) => sendResponse({ ok: true, data }))
|
|
.catch((err) => sendResponse({ ok: false, error: err instanceof Error ? err.message : String(err) }));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
});
|
|
});
|
|
|
|
/** 代理取图,返回 base64 data URL(结构化克隆可安全跨消息传递) */
|
|
async function fetchImageAsDataUrl(url: string): Promise<string> {
|
|
const res = await fetch(url);
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
const type = res.headers.get('content-type') || 'image/jpeg';
|
|
const buf = await res.arrayBuffer();
|
|
const bytes = new Uint8Array(buf);
|
|
|
|
// 分块转二进制串,避免超长参数列表
|
|
let bin = '';
|
|
const chunk = 0x8000;
|
|
for (let i = 0; i < bytes.length; i += chunk) {
|
|
bin += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
}
|
|
return `data:${type};base64,${btoa(bin)}`;
|
|
}
|