javascript 在Chrome扩展中,需要帮助将变量传递到当前选项卡

eyh26e7m  于 2023-08-02  发布在  Java
关注(0)|答案(1)|浏览(129)

我正在尝试Chrome扩展程序在同一标签页中逐个打开列表中的URL。当一个URL被打开时,我希望列表中相应的序列号可以作为打开的页面控制台中的一个变量。

{
  "manifest_version": 2,
  "name": "URL Opener",
  "version": "1.0",
  "description": "Open URLs from a list and execute code snippets.",
  "permissions": ["tabs", "activeTab"],
  "browser_action": {
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content_script.js"]
    }
  ],
  "web_accessible_resources": ["execute_code.js"]
}

字符串
popup.js

let urls = [
  {
    "serial": 1,
    "url": "https://www.example.com",
    "codeSnippet": `console.log("Hello, World! It's an example.");`,
    "uniqueString": "example123"
  },
  {
    "serial": 2,
    "url": "https://www.google.com",
    "codeSnippet": `alert('This is Google! "Search the world"');`,
    "uniqueString": "google456"
  },
  // Add more URLs with their respective fields as needed
];

let currentIndex = 0;

function openNextURL() {
  if (currentIndex >= urls.length) {
    alert("All URLs from the list have been opened.");
    return;
  }

  let urlObj = urls[currentIndex];

  // Get the current tab
  chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
    if (tabs.length > 0) {
      let currentTabId = tabs[0].id;

      // Update the current tab with the new URL
      chrome.tabs.update(currentTabId, { url: urlObj.url }, () => {
        currentIndex++;
        updatePopupUI(urlObj);

        // Send message to the content script to execute the code snippet
        chrome.tabs.sendMessage(
          currentTabId,
          { type: "EXECUTE_CODE", tabId: currentTabId, serial: urlObj.serial },
          (response) => {
            if (chrome.runtime.lastError) {
              console.error("Failed to execute code in content script:", chrome.runtime.lastError);
            } else if (response && response.success) {
              console.log(`URL Serial on page: ${response.urlSerial}`);
            } else {
              console.log("Failed to set URL Serial on page.");
            }
          }
        );
      });
    }
  });
}

function updatePopupUI(urlObj) {
  if (currentIndex < urls.length) {
    document.getElementById("current-url").innerText = `Opening URL ${urlObj.serial} of ${urls.length}:`;
    document.getElementById("url-details").innerHTML = `
      <strong>URL:</strong> ${urlObj.url}<br>
      <strong>Code Snippet:</strong><br>
      <pre>${escapeHTML(urlObj.codeSnippet)}</pre><br>
      <strong>Unique String:</strong> ${urlObj.uniqueString}
    `;
    document.getElementById("open-button").innerText = "Open Next URL";
  } else {
    document.getElementById("current-url").innerText = "All URLs have been opened!";
    document.getElementById("url-details").innerHTML = "";
    document.getElementById("open-button").disabled = true;
  }
}

function escapeHTML(str) {
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}

document.getElementById("open-button").addEventListener("click", openNextURL);
updatePopupUI(urls[currentIndex]);


content_script.js
//content_script.js

// This content script will be injected into all web pages

// The execute_code.js script will be dynamically injected into the page
const executeCodeScript = document.createElement("script");
executeCodeScript.src = chrome.runtime.getURL("execute_code.js");
(document.head || document.documentElement).appendChild(executeCodeScript);
executeCodeScript.onload = function () {
  executeCodeScript.remove();
};

// Listen for messages from the popup
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  if (message.type === "EXECUTE_CODE") {
    // Execute the code snippet
    chrome.scripting.executeScript({
      target: { tabId: message.tabId },
      files: ["execute_code.js"],
    });

    // Set URL serial variable in the page's context and send response back to popup
    let serial = message.serial;
    chrome.scripting.executeScript(
      {
        target: { tabId: message.tabId },
        func: (serial) => {
          window.urlSerial = serial;
        },
        args: [serial],
      },
      () => {
        // Send a response back to the popup after setting the URL serial variable
        sendResponse({ success: true, urlSerial: serial });
      }
    );

    // Return true to indicate that the response will be sent asynchronously
    return true;
  }
});


网址打开一个接一个,当我点击弹出窗口。但是,从未在控制台中获得变量urlSerial。

41zrol4v

41zrol4v1#

1.内容脚本不能使用大多数chrome API,如chrome.scripting。

  1. scripting API仅在ManifestV3中可用。
  2. activeTab只在调用(点击)扩展时对标签页中的站点起作用,当您将标签页导航到另一个站点时,它将不起作用,因此您需要在host_permissions中显式添加站点。

解决方案是在executeScript中指定MAIN world,直接在页面上下文中运行内容脚本代码,而不是单独的文件和消息传递。

1.删除content_scriptsweb_accessible_resources,content_script.js,execute_code.js
1.将browser_action重命名为action,并更新manifest.json中的这些字段:

"manifest_version": 3,
  "permissions": ["scripting"],
  "host_permissions": ["https://www.example.com/", "https://www.google.com/"],
  "action": {

字符串
1.更新popup.js:

async function openNextURL() {
  const [{id: tabId}] = await chrome.tabs.query({active: true, currentWindow: true});
  const urlObj = urls[currentIndex];
  await chrome.tabs.update(tabId, {url: urlObj.url});
  try {
    await chrome.scripting.executeScript({
      world: 'MAIN',
      target: {tabId},
      args: [urlObj.serial],
      func: s => { window.urlSerial = s; },
    });
  } catch (err) {
    document.body.insertAdjacentText('beforeend', err);
  }
}

相关问题