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

4

8

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"
}
Marigolda answered 15/6, 2017 at 12:27 Comment(8)
Could you add the content of your manifest.json to your post?Guaranty
Hi @Forivin, I added manifest.json to my post.Marigolda
I couldn't reproduce your issue. But I noticed two things: You never defined MyFunc in your Browser.js. And I get Content Security Policy errors.Guaranty
I defined MyFunc for using in another contentscript, could you give a example with this same case for me? Thanks.Marigolda
I also have this error.Marigolda
I defined window.MyFunc = window.MyFunc || {}; and I forget insert to comment.Marigolda
could you give a example with this same case for me? I'm not sure what you are asking for.Guaranty
I think browser.tabs.executeScript return arr, string,.. not allow return a function or class, I want to return a function or class for using in other scripts and I also have this issue.Marigolda
C
6

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

Culver answered 27/6, 2017 at 7:46 Comment(1)
I thought this affected only the finished and not error promise. Thank you for enlightening me.Adroit
G
4

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.

Guaranty answered 15/6, 2017 at 15:15 Comment(0)
M
0

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.

Mastership answered 14/6, 2019 at 11:21 Comment(0)
S
0

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

Streamline answered 10/3, 2022 at 22:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.