content_20250812172518.ts 3.2 KB

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