Why the callback result of the chrome.tabs.executeScript method return always an empty object?

652 Views Asked by At

I recently discovered the chrome extension development and got stuck with the runtime.excuteScript method, the callback in 3rd argument systematically returns me an empty object ...

For brevity, I will spare you all of my manifest.json(v2):

manifest permissions:

  "permissions": [
    "storage",
    "cookies",
    "tabs",
    "background",
    "activeTab",
    "<all_urls>",
    "*://*/*"
  ]

manifest content-script:

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "run_at": "document_end",
      "js": ["js/content-script.js"]
    }
  ]

My goal is to send the content of the localStorage to my extension.

pop-up.js:

chrome.tabs.executeScript(
  null, 
  { file: "js/content-script.js" },
  (result) => {
    if(result) console.log( " Result of content-script:",result ) 
    else console.log(" No content-script, no result")
  }
);

content-script.js:

localStorage;

output in the console of extension:

 Result of content-script: Array(1)
   ▶︎ 0: {} 
   length:1
   ▶︎ __proto__: Array(0)

Please make this a wonderful evening by explaining the mistake to me! Thank you!

3

There are 3 best solutions below

0
On

for me, it turned out to be the tab to execute the script is not fully loaded, so that the script did not run at all. now, i have a small pulling logic to check the tab status and execute the script after its status becomes to be 'complete'. it now returns the boolean value with no problem.

  function waitForTabToLoad(tabId: number): Promise<void> {
    return new Promise((resolve) => {
      const checkStatus = async () => {
        const tab = await chrome.tabs.get(tabId);

        if (tab.status === 'complete') {
          resolve();
        } else {
          setTimeout(checkStatus, 100);
        }
      };

      checkStatus();
    });
  }
  await waitForTabToLoad(newTabId);

  const isValidTab = () => {
    const textarea = document.querySelector('textarea');
    return !!textarea;
  };
  const results = await chrome.scripting.executeScript({ target: { tabId }, func: isValidTab });
0
On

I never found the solution. But I got around the problem by sending my data with this methode:

▼ content-script.js:

chrome.runtime.sendMessage({'localStorage' : localStorage});

▼ pop-up.js:

chrome.runtime.onMessage.addListener((message) => {message.localStorage});
0
On

For me, it was because I was returning an unserializable object in my func.

Must return something simple like String or int. The issue is that no exception is thrown, it silently erases the result