带有“假”导航的 SPA 网站上特定 URL 的内容脚本

问题描述 投票:0回答:1

目前我正在测试这段代码。我的目的是使用内容脚本抓取一些数据

这是我的后台文件

chrome.action.onClicked.addListener( (tab) => {
    // chrome.scripting.executeScript({
    //     target: {tabId: tab.id},
    //     files: ['content.js']
    //   })
    console.log('Requesting tab: \n', tab)
    chrome.windows.create({
        type: 'popup',
        height: 300,
        width: 200,
        url: chrome.runtime.getURL('popup.html')
    })
})

这就是我的内容脚本中的内容


console.info('chrome-ext template-vue-js content script')


const DOMnodes = document.querySelectorAll('article')

console.log(`Ecco le informazioni sui prezzi per Sole365`)
console.log('\n')


let details = []

DOMnodes.forEach( (node) => {
    // Loop nodi prodotto
    details.push(node.dataset)
    console.log(`----\n`)
    console.log(`Nome prodotto: ${node.dataset.productName}`)
    console.log(`Descrizione breve: ${node.children[2].children[1].childNodes[1].childNodes[0].innerText}`)
    // price 
    console.log(`Prezzo: ${node.childNodes[2].childNodes[1].childNodes[2].childNodes[0].innerText}`)
    //console.log(``)
    //descriz. breve
    //node.children[2].children[1].childNodes[1].childNodes[0].innerText
})

console.log(details)

当我在清单中设置的网站匹配时,脚本不会执行。这是开发版本

{
  "name": "create-chrome-ext",
  "description": "Extract data",
  "version": "1.0.0",
  "manifest_version": 3,
  "icons": {
    "16": "img/logo-16.png",
    "32": "img/logo-34.png",
    "48": "img/logo-48.png",
    "128": "img/logo-128.png"
  },
  "action": {
    "default_icon": "img/logo-48.png"
  },
  "options_page": "options.html",
  "background": {
    "service_worker": "service-worker-loader.js",
    "type": "module"
  },
  "host_permissions": [
    "https://www.example.com/mypath/*/*"
  ],
  "content_scripts": [
    {
      "js": [
        "assets/content-script.js"
      ],
      "matches": [
        "https://www.example.com/mypath/*/*"
      ]
    }
  ],
  "web_accessible_resources": [
    {
      "matches": [],
      "resources": [
        "img/logo-16.png",
        "img/logo-34.png",
        "img/logo-48.png",
        "img/logo-128.png"
      ],
      "use_dynamic_url": false
    },
    {
      "matches": [
        "<all_urls>"
      ],
      "resources": [
        "**/*",
        "*"
      ],
      "use_dynamic_url": true
    }
  ],
  "permissions": [
    "activeTab",
    "tabs",
    "alarms"
  ]
}

知道为什么吗?我的想法是在单击图标时调用脚本并打开一个弹出窗口以获取提取的数据以在 vue frontent 中使用

javascript google-chrome-extension chrome-extension-manifest-v3 content-script
1个回答
2
投票

问题 #1 是在 Chrome 中,您需要 重新注入内容脚本 来处理重新加载/更新/安装。

问题 #2 是该网站是一个现代 SPA(单页应用程序),它通过

history.pushState
或哈希片段伪造导航,因此页面文档保持不变,内容脚本不会重新运行。如果用户首先打开一个不匹配的 URL(例如网站的主页),它根本不会运行。

  • 对整个网站使用

    matches
    ,例如
    *://www.example.com/*

  • 在内容脚本中使用 MutationObserver,并检查是否存在要定位的泄露元素,或者检查

    location.href
    是否已更改为全局变量中先前保存的值,例如:

    let lastUrl = location.href; 
    new MutationObserver(() => {
      const url = location.href;
      if (url !== lastUrl) {
        lastUrl = url;
        onUrlChange();
      }
    }).observe(document, {subtree: true, childList: true});
    
    function onUrlChange() {
      console.log('URL changed!', location.href);
    }
    
  • 或者,如果您有后台脚本,请使用

    chrome.webNavigation.onHistoryStateUpdated
    onReferenceFragmentUpdated
    。可以通过URL过滤器进行限制。这些事件的侦听器将向事件的选项卡 ID 发送一条消息,您的内容脚本将接收该消息 (example)。

验证这是一个 SPA:

  1. 打开开发工具 -> 网络面板
  2. 在请求类型的工具栏过滤器中单击
    Doc
    Document
    HTML
  3. 单击页面中的链接可在网站内导航
  4. 查看对链接 URL 的请求是否添加到网络日志中
© www.soinside.com 2019 - 2024. All rights reserved.