4
<script src="myscript.js?someParameter=123"></script>

From within myscript.js, is there any way to obtain that someParameter was set to 123? Or is the only way to use server side scripts that generate the javascript file with the parameters in it?

Vilx-
  • 104,512
  • 87
  • 279
  • 422
  • possible duplicate of [How to pass parameters to a Script tag?](http://stackoverflow.com/questions/5292372/how-to-pass-parameters-to-a-script-tag) – Andy E Nov 03 '11 at 09:10
  • 1
    Not like this, but the file can access variables set in the "calling" file, and the calling file can call methods defined in the included file to initialize things. – Dave Newton Nov 03 '11 at 09:11
  • Yes, and you can explicitly call an initialization function from the calling file, etc. I was wondering however if this specific approach was feasible, as it is the (syntactically) simplest one. – Vilx- Nov 03 '11 at 10:17

3 Answers3

2

Well, you get URL parameters from window.location.href. As the name says, it refers to the current window. What the <script> tag does it to embed the linked file into the current document, thus into the same window. If you parsed window.location.href from the linked JavaScript file, you'd only get the URL from the embedding document.

There are two ways to pass parameters to another JavaScript file:

  1. As @Dave Newton suggested, just declare a variable, then embed the JS file like you did (without the parameters of course, because they have no effect).
  2. Create an iframe, pass the parameters you want to the URL of the iframe, then embed the JavaScript file inside the iframe. An iframe will create a new window instance.
Fabian
  • 4,160
  • 20
  • 32
  • OK, I'll accept your answer. I know of other ways, I just wondered if this was feasible. – Vilx- Nov 03 '11 at 10:16
  • Which other ways do you know? – Fabian Nov 03 '11 at 10:23
  • Well, there are the two you proposed. A more classical variation is to require a call to an initialization code by the calling file. In a thread which was proposed as a duplicate (it is, I think), there were two other scenarios. Both relied on the fact that the last ` – Vilx- Nov 03 '11 at 10:42
  • Then you can also go the HTML5 way and create a HTML element with `data-` attributes. You can put them on the ` – Vilx- Nov 03 '11 at 10:44
  • Also passing arguments as link attributes works - https://stackoverflow.com/questions/5292372/how-to-pass-parameters-to-a-script-tag – lubosdz Nov 09 '22 at 12:45
1

The answer is a definite "YES". I've been doing this on various projects for over a decade. The solution is actually easy, it's just non-intuitive (you have to generate an error). To be clear, the following code lets you do something like this:

<script src="https://example.com/script.js?id=1&bar=this works!" />

All you need to do is initiate a silent error, which takes less than 1/1000 of a second even on the worst outdated mobile browsers. You shouldn't do it a ton, but you only need to do it once. This error is processed, so it won't show up as an error in telemetry or 3rd party error trackers either.

    // Generic function used to see if a param exists in a URL string.
    // Provided here in case you don't know how to do it.
    // This is not needed for the solution.
    function getParameter (name, url) {
      if (!url) url = scriptName()
      name = name.replace(/[\[\]]/g, '\\$&')
      var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')
      var results = regex.exec(url)
      if (!results) return null
      if (!results[2]) return ''
      return decodeURIComponent(results[2].replace(/\+/g, ' '))
    }
  
    // Gets the name of this script (whatever this file runs in)
    // You can use this name to get parameters just like you would for the window URL :)
    function getScriptName () {
      var error = new Error(),
        source,
        lastStackFrameRegex = new RegExp(/.+\/(.*?):\d+(:\d+)*$/),
        currentStackFrameRegex = new RegExp(/getScriptName \(.+\/(.*):\d+:\d+\)/)
  
      if ((source = lastStackFrameRegex.exec(error.stack.trim())) && source[1] !== '')
        return source[1]
      else if ((source = currentStackFrameRegex.exec(error.stack.trim())))
        return source[1]
      else if (error.fileName !== undefined)
        return error.fileName
    }
Nick Steele
  • 7,419
  • 4
  • 36
  • 33
  • Amazing, but there is a little error, you must rename " if (!url) url = scriptName()" in "if (!url) url = getScriptName()" – Payedimaunt Feb 24 '23 at 11:53
1

Jquery Address does this, so i've been checking their code out and this is the improved solution I just created myself:

$.each($('script'), function(id, val){ //loop trough all script-elements
    var tmp_src = String($(this).attr('src'));//store the src-attr
    var qs_index = tmp_src.indexOf('?');//check if src has a querystring and get the index

    //Check if the script is the script we are looking for and if it has QS-params
    if(tmp_src.indexOf('myscript.js') >= 0 && qs_index >= 0)
    {
        //this is myscript.js and has a querystring
            //we want an array of param-pairs: var1 = value1, var2 = value2, ...
        var params_raw = tmp_src.substr(qs_index + 1).split('&');

        //create empty options array
        var options = [];

        //loop troug raw params
        $.each(params_raw, function(id, param_pair){
                    //split names from values
            var pp_raw = param_pair.split('=');
                    //store in options array
            options[pp_raw[0]] = pp_raw[1];
        });
            //check the results out in the console!
        console.log(options);
    }
});

I hope this does what you need?

Stijn_d
  • 1,078
  • 9
  • 20