Tam Vo
Tam Vo

Reputation: 331

Inject scripts error: Script returned non-structured-clonable data on Firefox extension

I want to inject script from firefox web extension to tabId thought browser.tabs.executeScript API.

I have a file Browser.js

MyFunc.Browser = (function() {
  var self;

  function Browser() {
    self = this;
  }

  Browser.getExtensionURI = function() {
    return "chrome-extension://";
  };

  return Browser;

})();

And execute script function:

var executing = browser.tabs.executeScript(tabId, {
            file: "js/contentscripts/Browser.js"
          });
 executing.then(function(results) {
    console.log("url: " + tabUrl + ", result", results);

 }, function(error) {
    return console.log("Inject scripts error: " + error);
 });

But script cannot inject to tab and show error.

How I can fix it?

Manifest file:

{
  "name": "abc",

  "background": {
    "page": "background.html"
  },
  "browser_action": {
    "default_icon": "icons/icon_19.png",
    "default_popup": "login.html",
  },
  "content_scripts": [
    {
      "web_accessible_resources": [


        "js/contentscripts/Browser.js",

      ],
      "js": [
        "js/contentscripts/ContentScript.js"
      ],
      "matches": [
        "file://*/*",
        "http://*/*",
        "https://*/*"
      ],
      "run_at": "document_end",
      "all_frames": true
    },
    {
      "js": [

        "js/contentscripts/Browser.js",
      ],
      "matches": [
        "file://*/*",
        "http://*/*",
        "https://*/*"
      ],
      "run_at": "document_start",
      "all_frames": true
    }
  ],
  "icons": {
    "16": "icons/icon_16.png",
    "19": "icons/icon_19.png"
  },
  "incognito": "spanning",
  "permissions": [
    "activeTab",
    "tabs",
    "http://*/*",
    "https://*/*",
    "<all_urls>"
  ],
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "version": "1.1.16"
}

Upvotes: 8

Views: 4892

Answers (4)

Madacol
Madacol

Reputation: 4286

I got same error trying to inject code that only made a dynamic import

import(...)

added a .then(x=>null) and solved it

import(...).then(x=>null)

I tried putting "" or undefined in last line, but I'm using the bundler rollup and it kept removing everything a put, since it thought it didn't affect anything

Upvotes: 0

Craig  Hicks
Craig Hicks

Reputation: 2548

According to MDN

The result of the script is the last evaluated statement,...

(Similarly to how a script bash function uses the last calculated result as its return result.)

That result must be one of the list of types in @Forivin's answer above. However, that is not a usual constraint on the last command in a script, so it catches a lot of people out, as seen by the many results when searching for the OP's error message.

Adding the string

"Browser.js END OF FILE"

to the end of your file Browser.js would (if that line was actually reached) safely set results to that string.

(Note: various handler and living objects in the script will continue computation, but the interpreter will have finished parsing the script, sequentially executing commands, and returned with that finally parsed line.)


In my case I got the error after refactoring the script left

window.onhashchange=winHashHandler;

as the last line. Simply placing a string on the line after that removed the error.

Upvotes: 0

Zero0evolution
Zero0evolution

Reputation: 81

in "js/contentscripts/Browser.js" file, add "undefined;" to last line.
the value will return to result of "executing.then" first callback argument
reference:https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/executeScript#Return_value

Upvotes: 6

Forivin
Forivin

Reputation: 15518

I think I understand your issue now.

The return data of your executeScript has to be structured clonable.
In order to be considered structured clonable the data has to match one of these data types:

  • All primitive types - However not symbols
  • Boolean object
  • String object
  • Date
  • RegExp - The lastIndex field is not preserved.
  • Blob
  • File
  • FileList
  • ArrayBuffer
  • ArrayBufferView - This basically means all typed arrays like Int32Array etc.
  • ImageData
  • Array
  • Object - This just includes plain objects (e.g. from object literals)
  • Map
  • Set

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#Supported_types

In your case the problem is that you are returning an object that has functions in it's properties. Thus it is non-structured-clonable, which explains your error.

Upvotes: 4

Related Questions