10

I'm currently trying to figure out how I can include a javascript, I have on my webserver, in my scriptish/greasemonkey script and make it reload the script everytime the userscript gets called.

I'm editing the script on my webserver and I really don't want to reinstall the userscript each time I make changes on the included script.

Is there any way around this problem? I've been searching for an answer but had no luck so far.

So to be clear, my userscript looks like this:

// ==UserScript==
// @id             HET
// @name           SettingsHandler
// @version        1.0
// @namespace      HET
// @require        http://urltoscript/scripts/he/lib.js
// @run-at         document-end
// ==/UserScript==

and my external script looks like this:

alert('got it');

All still very easy for testing purposes. This setup works, but only the first time and when I change my lib.js script, then the userscript still reads the old one. Is there a way to prevent the userscript from caching the external script? Or is there any other metatag that can help me?

Thanks in advance, Dave

DaMaGeX
  • 673
  • 5
  • 17
  • http://stackoverflow.com/questions/9210542/node-js-require-cache-possible-to-invalidate – Andreas May 07 '15 at 19:09
  • 3
    How does this apply to Scriptish or Greasemonkey? – DaMaGeX May 07 '15 at 19:11
  • 1
    [`@require` is for caching at install time.](http://wiki.greasespot.net/Metadata_Block#.40require) - "Each @require is downloaded once, when the script is installed, and stored on the user's hard drive alongside the script." If you don't want caching, just insert a ` – rampion May 10 '15 at 02:46
  • 1
    @rampion huh? – Ryan Lee Aug 31 '19 at 01:19
  • @RyanLee Rob M’s answer below does exactly what I said. – rampion Aug 31 '19 at 02:53

4 Answers4

5

Not sure how to accomplish this with GM/userscript directives, but you could easily add the script yourself and append a timestamp to the url to prevent the browser from caching it:

var remoteScript = document.createElement('script');
remoteScript.src = 'http://domain.com/path/to/script.js?ts='+(+new Date());
remoteScript.onload = init;
document.body.appendChild(remoteScript);

function init() {
  ... do stuff
}
Rob M.
  • 33,381
  • 6
  • 50
  • 46
  • 4
    That wont work with CSP blocking you from accessing `domain.com`. – coulix Feb 25 '17 at 05:51
  • @TomášZato: The question said the `@require` directive would point to JS code on "[their] web server" so I don't think local files are an issue. – Alex Quinn Feb 01 '18 at 16:33
4

Here is the only workable answer https://github.com/Tampermonkey/tampermonkey/issues/475

Recommended is option 4. However they are loaded asynchronously so loading orders might differ

There are several ways to ease your pain. :)

  1. You can increase the version number before saving the script and all external resources will be reloaded.
  2. After setting "Config mode" to "Advanced" you can configure the external update interval. Note: "Always" still means after the resource was used. So you might need to execute/load the page twice.
  3. If you use Tampermonkey Beta (Chrome or Firefox) you can edit the external resource in place (because there now is a edit button besides the delete button).
  4. Copy the resources and store them locally. After you've enabled "Local file access" at Chrome's extension management page or Tampermonkey's settings page (if you're using Firefox) you can @require them via a local file:// URI.
Ryan Lee
  • 1,215
  • 2
  • 15
  • 22
1

The answer from Rob M. doesn't work for me, because Tampermonkey script location and target site where it got injected could be different. For example, in my case I also have a locally running webserver to develop in an IDE using Tampermonkey for Firefox without requiring any file system access for Tampermonkey from the Browser.

This script should got injected to a third party site like example.com, where it applys modifications. So the browser would block this script, since it's from a different domain than example.com.

During development, I'd like to get my script without any caching to apply changes immediately. Worked around this by fetching the scripts content using `GM.xmlHttpRequest. Additionally, a GET parameter with the current timestamp acts as cache buster:

let url = `http://localhost/myscript.js?ts=${(+new Date())}`

GM.xmlHttpRequest({
    method: "GET",
    url: url,
    onload: function(response) {
        let remoteScript = document.createElement('script')
        remoteScript.id = 'tm-dev-script'
        remoteScript.innerHTML = response.responseText
        document.body.appendChild(remoteScript)
    }
})

Notice that since GM.xmlHttpRequest can bypass the same origin policy, access musst be explicitly granded in the head of your script:

// @grant        GM.xmlHttpRequest
Rob Kwasowski
  • 2,580
  • 3
  • 10
  • 31
Lion
  • 14,320
  • 17
  • 71
  • 129
  • This is the only solution here that worked for me (not only because I have it on different domain e.g. localhost or similar), but also because my Firefox 82 forces http:// to https:// . Thank you very much! – Tomáš Diviš Dec 01 '20 at 12:22
-1

You can add the following to your .htaccess file:

<FilesMatch "filename.js">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
</FilesMatch>

And remove it when you are done developing.

Sidd
  • 1,379
  • 7
  • 17
  • do you even know what tampermonkey is? – Faizan Anwer Ali Rupani Aug 20 '17 at 16:41
  • Sure, although I didn't think that was particularly relevant to the question. – Sidd Aug 20 '17 at 17:27
  • This answer is correct. The question said their @require directive would point to JS code on "[their] web server". If that server runs Apache, then this .htaccess code should solve the problem just fine. – Alex Quinn Feb 01 '18 at 16:29
  • 1
    not specific to tampermonkey. does not solve the issue when using require with tampermonkey. for example, my require is calling a raw file from GitHib where I manage my script. Tampermonkey is not updating it, so a solution is needed to stop tampermonkey caching scripts and to call the fresh one each time. – Laurence Cope May 08 '18 at 08:33