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.