Come passare i parametri a un tag Script?


96

Ho letto il tutorial Widget fai da te - Come incorporare il tuo sito su un altro sito per XSS Widgets di Dr. Nic.

Sto cercando un modo per passare parametri al tag script. Ad esempio, per fare il seguente lavoro:

<script src="http://path/to/widget.js?param_a=1&amp;param_b=3"></script>

C'è un modo per fare questo?


Due link interessanti:


Risposte:


124

Mi scuso per aver risposto a una domanda super vecchia ma dopo aver passato un'ora a lottare con le soluzioni di cui sopra ho optato per cose più semplici.

<script src=".." one="1" two="2"></script>

All'interno dello script sopra:

document.currentScript.getAttribute('one'); //1
document.currentScript.getAttribute('two'); //2

Molto più semplice dell'analisi di jquery o URL.

Potresti aver bisogno del polyfil per doucment.currentScript dalla risposta di @Yared Rodriguez per IE:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();

6
Nota che currentScript non funziona in IE. Dettagli
Dehli

Ho aggiunto un polyfill per IE nella risposta. Il polyfill non funziona?
Richard Fox

2
il polyfill non funziona più, document.currentScript è di sola lettura e non può essere assegnato se già esiste. forse un controllo diverso come se (! document.currentScript) {*** la funzione polyfill ***} funzionasse meglio
fadomire

3
Mi scuso David, rendo sempre le mie risposte generiche in modo che altri possano utilizzare la soluzione senza che i dettagli di implementazione iniziali si aggiungano ai problemi. Nel mio esempio sopra puoi vedere src="..."Questo significa che QUALSIASI src, non importa :)
Richard Fox

1
@RichardFox grazie per la risposta, ma dovevo solo commentare che "Non risponde alla domanda originale: non usa path / to / widget.js" è probabilmente la cosa più divertente che ho letto in tutta la settimana! Non riesco a credere che tu abbia risposto così bene come hai fatto.
Skintest

65

È meglio usare la funzionalità negli attributi di dati 5 html5

<script src="http://path.to/widget.js" data-width="200" data-height="200">
</script>

All'interno del file di script http://path.to/widget.js puoi ottenere i paremeters in questo modo:

<script>
function getSyncScriptParams() {
         var scripts = document.getElementsByTagName('script');
         var lastScript = scripts[scripts.length-1];
         var scriptName = lastScript;
         return {
             width : scriptName.getAttribute('data-width'),
             height : scriptName.getAttribute('data-height')
         };
 }
</script>

E se id = "myAwesomeWigretNo1" non fosse sempre così ma myAwesomeWigretNo2, o myAwesomeWigretNo681??? Come posso risolvere questo problema per accettare una variabile reale?
Pathros

9
Per quel che vale, ci sono altri modi per fare riferimento alla sceneggiatura, invece, come ad esempio document.currentScript(funziona solo per gli script non nel proprio file) e di porre idsul <script>tag e poi trovare da parte di quest'ultimo.
Thunderforge

E se l'ID fosse stato modificato da qualche altro programmatore del tuo team che non aveva la minima idea che tu lo usi?
OBender

1
Se carichi gli script in modo asincrono, l'utilizzo di un ID è l'unica opzione affidabile che consiglierei. Grazie @Thunderforge ... Inoltre, qualsiasi programmatore dovrebbe astenersi dal refactoring di un codice senza un adeguato piano di sprint controllato da qualcuno che ha un'idea di cosa sta succedendo;)
Luca Borrione

Sicuramente puoi richiedere una forte etica agli sviluppatori, ma non funzionerà a lungo termine ... La gente dimentica le cose ... In un buon software design ogni blocco calzato deve essere isolato, awesome-pixels.tumblr.com/post/101930002170 /… En.wikipedia.org/wiki/SOLID_(object-oriented_design) Quindi non sostengo che sia una soluzione buona o cattiva, è solo più complesso mantenere gli ID invece di non mantenerli :-) Non hai intenzione di farlo caricare lo script Async non vedo alcun motivo per caricare utilizzando ID
OBender

17

Fatto. Una specie di hack, ma funziona abbastanza bene:

var params = document.body.getElementsByTagName('script');
query = params[0].classList;
var param_a = query[0];
var param_b = query[1];
var param_c = query[2];

Passo i parametri nel tag script come classi:

<script src="http://path.to/widget.js" class="2 5 4"></script>

Questo articolo ha aiutato molto.


1
L'articolo è fantastico!
Bartek Skwira

14
Le classi dovrebbero essere usate per definire gli elementi per non passare i parametri.
kspacja

5
@kspacja Sì e l'HTML dovrebbe contenere solo contenuto senza stile, tranne per il fatto che dobbiamo ordinare con precisione i nostri tag DIV per i layout float e di colonna perché i CSS non possono effettivamente fare il lavoro, e in qualche modo ci va bene. Hack away, dico. Ma puoi usare gli attributi "data-" se vuoi evitare conflitti o se sei il tipo che ci perde il sonno.
Jason C

14

Un altro modo è usare i meta tag. Qualunque dato debba essere passato al tuo JavaScript può essere assegnato in questo modo:

<meta name="yourdata" content="whatever" />
<meta name="moredata" content="more of this" />

I dati possono quindi essere estratti dai meta tag in questo modo (meglio farlo in un gestore di eventi DOMContentLoaded):

var data1 = document.getElementsByName('yourdata')[0].content;
var data2 = document.getElementsByName('moredata')[0].content;

Assolutamente nessun problema con jQuery o simili, non sono necessari hack e soluzioni alternative e funziona con qualsiasi versione HTML che supporti i meta tag ...


Ho pensato che questo metodo fosse di gran lunga il metodo più semplice di tutti. Funziona come un incantesimo e mi dà esattamente ciò di cui ho bisogno. Ottima domanda e soluzione fantastica!
arios

10

JQuery ha un modo per passare parametri da HTML a javascript:

Metti questo nel myhtml.htmlfile:

<!-- Import javascript -->
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<!-- Invoke a different javascript file called subscript.js -->
<script id="myscript" src="subscript.js" video_filename="foobar.mp4">/script>

Nella stessa directory crea un subscript.jsfile e mettilo lì:

//Use jquery to look up the tag with the id of 'myscript' above.  Get 
//the attribute called video_filename, stuff it into variable filename.
var filename = $('#myscript').attr("video_filename");

//print filename out to screen.
document.write(filename);

Analizza risultato:

Il caricamento della pagina myhtml.html ha la stampa "foobar.mp4" sullo schermo. La variabile denominata video_filename è stata passata da html a javascript. Javascript lo ha stampato sullo schermo e sembrava incorporato nell'html nel genitore.

jsfiddle prova che quanto sopra funziona:

http://jsfiddle.net/xqr77dLt/


7

Se stai usando jquery potresti prendere in considerazione il loro metodo di dati.

Ho usato qualcosa di simile a quello che stai cercando nella tua risposta, ma in questo modo:

<script src="http://path.to/widget.js" param_a = "2" param_b = "5" param_c = "4">
</script>

Potresti anche creare una funzione che ti consenta di prendere direttamente i parametri GET (questo è quello che uso frequentemente):

function $_GET(q,s) {
    s = s || window.location.search;
    var re = new RegExp('&'+q+'=([^&]*)','i');
    return (s=s.replace(/^\?/,'&').match(re)) ? s=s[1] : s='';
}

// Grab the GET param
var param_a = $_GET('param_a');

4

Grazie a jQuery, una semplice soluzione conforme a HTML5 è creare un tag HTML aggiuntivo, come div, per memorizzare i dati.

HTML :

<div id='dataDiv' data-arg1='content1' data-arg2='content2'>
  <button id='clickButton'>Click me</button>
</div>

JavaScript :

$(document).ready(function() {
    var fetchData = $("#dataDiv").data('arg1') + 
                    $("#dataDiv").data('arg2') ;

    $('#clickButton').click(function() {
      console.log(fetchData);
    })
});

Demo live con il codice sopra: http://codepen.io/anon/pen/KzzNmQ?editors=1011#0

Nella demo live, è possibile vedere i dati dagli attributi data- * HTML5 da concatenare e stampare nel registro.

Fonte: https://api.jquery.com/data/


1
Ho esaminato alcune delle altre soluzioni, ma questa è stata quella che ha funzionato meglio ed è anche piuttosto semplice da implementare. Grazie!
Erik Kalkoken

Questa dovrebbe essere la soluzione accettata, poiché consente di fare riferimento allo script tramite ID ed è HTML5 valido.
Tim S

4

è un thread molto vecchio, lo so, ma anche questo potrebbe aiutare se qualcuno arriva qui una volta che cerca una soluzione.

Fondamentalmente ho usato document.currentScript per ottenere l'elemento da cui è in esecuzione il mio codice e filtro utilizzando il nome della variabile che sto cercando. L'ho fatto estendendo currentScript con un metodo chiamato "get", quindi saremo in grado di recuperare il valore all'interno di quello script usando:

document.currentScript.get('get_variable_name');

In questo modo possiamo utilizzare l'URI standard per recuperare le variabili senza aggiungere attributi speciali.

Questo è il codice finale

document.currentScript.get = function(variable) {
    if(variable=(new RegExp('[?&]'+encodeURIComponent(variable)+'=([^&]*)')).exec(this.src))
    return decodeURIComponent(variable[1]);
};

Mi stavo dimenticando di IE :) Non potrebbe essere più facile ... Beh, non ho detto che document.currentScript è una proprietà HTML5. Non è stato incluso per diverse versioni di IE (ho provato fino a IE11 e non c'era ancora). Per la compatibilità con IE, ho aggiunto questa parte al codice:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();

Quello che stiamo facendo qui è definire un codice alternativo per IE, che restituisce l'oggetto script corrente, che è richiesto nella soluzione per estrarre i parametri dalla proprietà src. Questa non è la soluzione perfetta per IE poiché ci sono alcune limitazioni; Se lo script viene caricato in modo asincrono. I browser più recenti dovrebbero includere la proprietà ".currentScript".

Spero possa essere d'aiuto.


4

Crea un attributo che contenga un elenco dei parametri, in questo modo:

<script src="http://path/to/widget.js" data-params="1, 3"></script>

Quindi, nel tuo JavaScript, ottieni i parametri come un array:

var script = document.currentScript || 
/*Polyfill*/ Array.prototype.slice.call(document.getElementsByTagName('script')).pop();

var params = (script.getAttribute('data-params') || '').split(/, */);

params[0]; // -> 1
params[1]; // -> 3

Quali sono gli svantaggi di questo approccio?
Tronathan

@Tronathan non ci sono veri svantaggi di questo approccio e c'è un polyfill incluso per un migliore supporto del browser. L'unico svantaggio che vedo qui è non essere in grado di includere virgole nei parametri, che di solito non è un problema, e puoi compensarlo cambiando il delimitatore in un carattere che non hai intenzione di utilizzare.
Mystical

2

Metti i valori di cui hai bisogno da qualche parte in cui l'altro script possa recuperarli, come un input nascosto, quindi estrai quei valori dal loro contenitore quando inizializzi il tuo nuovo script. Potresti persino mettere tutti i tuoi parametri come stringa JSON in un campo nascosto.


Grazie per aver risposto. I parametri sono effettivamente inseriti dagli utenti (che incorpora questo tag di script nel loro codice). Cosa poi?
Tomer Lichtash

L'unica cosa a cui posso pensare se non hai il controllo su entrambi gli script client / server è prendere l'input degli utenti e usarlo per generare un file .js specifico con il loro input incorporato in esso, e questo presuppone che tu abbia il controllo di raccogliere ed elaborare il loro input.
bwest

Non risponde alla domanda originale: dove mettere gli argomenti quando non c'è un modulo per contenere il campo Nascosto?
David Spector

2

Volevo soluzioni che supportassero quanto più possibile i vecchi browser. Altrimenti direi che il metodo currentScript o il metodo degli attributi dei dati sarebbero più eleganti.

Questo è l'unico di questi metodi non ancora menzionato qui. In particolare, se per qualche motivo disponi di grandi quantità di dati, l'opzione migliore potrebbe essere:

memoria locale

/* On the original page, you add an inline JS Script: */
<script>
   localStorage.setItem('data-1', 'I got a lot of data.');
   localStorage.setItem('data-2', 'More of my data.');
   localStorage.setItem('data-3', 'Even more data.');
</script>

/* External target JS Script, where your data is needed: */
var data1 = localStorage.getItem('data-1');
var data2 = localStorage.getItem('data-2');
var data3 = localStorage.getItem('data-3');

localStorage ha un supporto completo per i browser moderni e un supporto sorprendentemente buono anche per i browser più vecchi, tra gli altri a IE 8, Firefox 3,5 e Safari 4 [undici anni fa].

Se non disponi di molti dati, ma desideri comunque un ampio supporto del browser, forse l'opzione migliore è:

Meta tag [di Robidu]

/* HTML: */
<meta name="yourData" content="Your data is here" />

/* JS: */
var data1 = document.getElementsByName('yourData')[0].content;

Il difetto di ciò è che il posto corretto per inserire i meta tag [fino all'HTML 4] è nel tag head e potresti non volere questi dati lassù. Per evitare ciò, o inserire meta tag nel corpo, potresti usare:

Paragrafo nascosto

/* HTML: */
<p hidden id="yourData">Your data is here</p>

/* JS: */
var yourData = document.getElementById('yourData').innerHTML;

Per un supporto ancora maggiore del browser, potresti utilizzare una classe CSS invece dell'attributo nascosto:

/* CSS: */
.hidden {
   display: none;
}

/* HTML: */
<p class="hidden" id="yourData">Your data is here</p>

2

Questa è la soluzione per jQuery 3.4

<script src="./js/util.js" data-m="myParam"></script>
$(document).ready(function () {
    var m = $('script[data-m][data-m!=null]').attr('data-m');
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.