1
Calling Script Directly (works) // ==UserScript== // @name Example // @version 0.1 // @description Script from a website // @author You // @match *://*.example.com/* // @grant none // @require https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js // @require https://code.jquery.com/jquery-3.2.1.min.js // ==/UserScript== /* script here: */ Calling Script Externally (doesn't work) // ==UserScript== // @name Example // @version 0.1 // @description Script from a website // @author You // @match *://*.example.com/* // @grant GM_xmlhttpRequest // @require https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js // @require https://code.jquery.com/jquery-3.2.1.min.js // @run-at document-start // ==/UserScript== GM_xmlhttpRequest({ method : "GET", url : "http://example.com/script.js", onload : (e) => { eval(e.responseText); } }); 

I need to load a JavaScript file stored from a separate site directly to a website using tampermonkey. Loading the code directly in a tampermonkey document works, except when you call it from a site.

3
  • You are sandboxed. You need to inject into page if it should be able to use the script. Commented Feb 6, 2019 at 2:50
  • @Quasimodo'sclone - Can you point to an example? I've seen that some things have changed over recent times (1 - 3 years?). Commented Jan 22, 2020 at 18:18
  • Sorry, I've been offline for some time. I've just provided an answer, hopefully I did understand your question correctly. Commented Jan 30, 2020 at 5:41

1 Answer 1

3

Loading the code directly in a tampermonkey document works, except when you call it from a site.

I understand your statement, that you try to invoke some GM-loaded functions from within the page's script.

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Userscript-Test</title> </head> <body> <button id="test-btn">injected script</button> <script> // invoke testFunction() which is loaded by the userscript. document.getElementById('test-btn').addEventListener('click', ev => testFunction()); </script> </body> </html> 

Your second userscript actually does work, however, by the default settings of current TamperMonkey versions the user will be asked to allow a cross-origin fetch for this domain if it does not match the same-origin-policy. If permitted, you can access the dynamically loaded script from your userscript after executing it via eval as you already have done.

Of course the script is evaluated within the TamperMonkey sandbox. Thus you do not have access from within the page.

You need to inject the script into the page to make it availabe to the page's scripts as well. E.g. you could dynamically create a <script> tag.

// ==UserScript== // @name Example // @version 0.1 // @description Script from a website // @author You // @match *://*.example.com/* // @grant GM_xmlhttpRequest // @run-at document-start // ==/UserScript== GM_xmlhttpRequest({ method : "GET", // from other domain than the @match one (.org / .com): url : "http://example.org/script.js", onload : (ev) => { let e = document.createElement('script'); e.innerText = ev.responseText; document.head.appendChild(e); } }); 

To be compatible with older userscript extensions, you might want to use unsafeWindow.document.head and @grant unsafeWindow. (However, be aware of security issues.)

You might also want @run-at document-start to ask the extension to run the script as soon as possible before any other scripts. At this early time, the DOM might not be ready yet. It's up to you to ensure when the DOM is ready to receive injections. Note that some addons do not guarantee when your userscript actually is started.

If the dynamically loaded script does not frequently change, consider to prefetch it on install using @resource and load it from the local storage. See also GM.getResourceUrl. You can use that URL to fetch the GM_xmlhttpRequest.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.