content_20250812172948.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. export default defineContentScript({
  2. matches: ["<all_urls>"],
  3. runAt: "document_idle", // 确保在页面加载完成后运行
  4. main(ctx) {
  5. console.log('Content script loaded on:', window.location.href);
  6. // 监听来自popup的消息
  7. const handleMessage = (request: any, sender: any, sendResponse: any) => {
  8. console.log('Received message:', request);
  9. // 处理测试消息
  10. if (request.action === "test") {
  11. sendResponse({ status: "success", message: "Content script is running" });
  12. return true;
  13. }
  14. if (request.action === "getImages") {
  15. try {
  16. // 获取页面上所有图片元素
  17. const imageElements = Array.from(document.querySelectorAll('img'));
  18. // 获取背景图片元素
  19. const allElements = Array.from(document.querySelectorAll('*'));
  20. const backgroundImages: Array<{url: string, element: string, class: string, id: string}> = [];
  21. // 提取<img>标签的图片
  22. const imgSources = imageElements
  23. .map(img => {
  24. let url = img.src;
  25. // 处理相对路径
  26. if (url && !url.startsWith('http') && !url.startsWith('data:')) {
  27. try {
  28. url = new URL(url, window.location.origin).href;
  29. } catch (e) {
  30. console.warn('Failed to resolve relative URL:', url);
  31. }
  32. }
  33. return {
  34. url,
  35. element: 'img',
  36. class: img.className || '',
  37. id: img.id || '',
  38. alt: img.alt || ''
  39. };
  40. })
  41. .filter(img => img.url && (img.url.startsWith('http') || img.url.startsWith('data:')));
  42. // 提取背景图片
  43. allElements.forEach(element => {
  44. const computedStyle = window.getComputedStyle(element);
  45. const backgroundImage = computedStyle.backgroundImage;
  46. // 检查是否有background-image
  47. if (backgroundImage && backgroundImage !== 'none' && backgroundImage.includes('url')) {
  48. // 提取URL
  49. const urlMatch = backgroundImage.match(/url\(["']?(.*?)["']?\)/);
  50. if (urlMatch && urlMatch[1]) {
  51. // 解码HTML实体
  52. const textarea = document.createElement('textarea');
  53. textarea.innerHTML = urlMatch[1];
  54. const decodedUrl = textarea.value;
  55. backgroundImages.push({
  56. url: decodedUrl,
  57. element: element.tagName.toLowerCase(),
  58. class: element.className || '',
  59. id: element.id || ''
  60. });
  61. }
  62. }
  63. });
  64. // 合并所有图片
  65. const allImages = [...imgSources, ...backgroundImages];
  66. console.log('Found images:', allImages);
  67. sendResponse({ images: allImages });
  68. } catch (error: any) {
  69. console.error('Error extracting images:', error);
  70. sendResponse({ images: [], error: error.message });
  71. }
  72. return true; // 保持消息通道开放
  73. }
  74. };
  75. // 添加消息监听器
  76. browser.runtime.onMessage.addListener(handleMessage);
  77. // 清理函数
  78. ctx.onInvalidated(() => {
  79. browser.runtime.onMessage.removeListener(handleMessage);
  80. });
  81. }
  82. });