Wie übergebe ich Parameter an ein Script-Tag?

87

Ich habe das Tutorial DIY Widgets gelesen - So binden Sie Ihre Site in eine andere Site für XSS Widgets von Dr. Nic ein.

Ich suche nach einer Möglichkeit, Parameter an das Skript-Tag zu übergeben. Zum Beispiel, damit Folgendes funktioniert:

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

Gibt es eine Möglichkeit, dies zu tun?


Zwei interessante Links:

Tomer Lichtash
quelle

Antworten:

117

Ich entschuldige mich für die Beantwortung einer super alten Frage, aber nachdem ich eine Stunde lang mit den oben genannten Lösungen gerungen hatte, entschied ich mich für einfachere Dinge.

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

Im obigen Skript:

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

Viel einfacher als jquery OR url parsing.

Möglicherweise benötigen Sie die Polyfil für doucment.currentScript aus der Antwort von @Yared Rodriguez für IE:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();
Richard Fox
quelle
5
Beachten Sie, dass currentScript im IE nicht funktioniert. Details
Dehli
Ich habe in der Antwort eine Polyfüllung für IE hinzugefügt. Funktioniert die Polyfüllung nicht?
Richard Fox
2
Die Polyfüllung funktioniert nicht mehr. document.currentScript ist schreibgeschützt und kann nicht zugewiesen werden, wenn es bereits vorhanden ist. Vielleicht würde eine andere Prüfung wie (! document.currentScript) {*** die Polyfill-Funktion ***} besser funktionieren
Fadomire
2
Ich entschuldige mich, David, ich mache meine Antworten immer allgemein, damit andere die Lösung verwenden können, ohne dass die anfänglichen Implementierungsdetails zu Problemen beitragen. In meinem obigen Beispiel können Sie sehen, dass src="..."dies bedeuten soll, dass JEDER src keine Rolle spielt :)
Richard Fox
1
@RichardFox danke für die Antwort, musste aber nur kommentieren, dass "Beantwortet die ursprüngliche Frage nicht: verwendet path / to / widget.js nicht" wahrscheinlich das lustigste ist, was ich die ganze Woche gelesen habe! Ich kann nicht glauben, dass du so gut geantwortet hast wie du.
Skintest
63

Es ist besser, die Funktion in HTML5 5- Datenattributen zu verwenden

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

In der Skriptdatei http://path.to/widget.js können Sie die Parameter auf folgende Weise abrufen:

<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>
OBender
quelle
Was ist, wenn die id = "myAwesomeWigretNo1" nicht immer so ist, aber myAwesomeWigretNo2, oder myAwesomeWigretNo681??? Wie kann ich das beheben, um eine echte Variable zu akzeptieren?
Pathros
9
Für das, was es wert ist, gibt es andere Möglichkeiten, stattdessen auf das Skript zu verweisen, z. B. document.currentScript(funktioniert nur für Skripte, die nicht in ihrer eigenen Datei enthalten sind) und ein Tag idauf das <script>Tag zu setzen und es dann zu finden.
Thunderforge
Und was ist, wenn die ID von einem anderen Programmierer in Ihrem Team geändert wurde, der keine Ahnung hatte, dass Sie diese ID verwenden?
OBender
1
Wenn Sie Skripte asynchron laden, ist die Verwendung einer ID die einzige zuverlässige Option, die ich empfehlen würde. Danke @Thunderforge ... Außerdem sollte jeder Programmierer es unterlassen, einen Code ohne einen richtigen Sprintplan umzugestalten, der von jemandem überblickt wird, der eine Ahnung hat, was los ist;)
Luca Borrione
Sicher, Sie können von Entwicklern eine starke Ethik verlangen, aber auf lange Sicht wird es nicht funktionieren ... Die Leute vergessen Dinge ... In einem guten Software-Design sollte jeder Block isoliert sein, awesome-pixels.tumblr.com/post/101930002170 /… En.wikipedia.org/wiki/SOLID_(object-oriented_design) Ich behaupte also nicht, dass es eine gute oder schlechte Lösung ist. Es ist nur komplexer, IDs zu pflegen und nicht zu pflegen :-) Planen Sie das nicht? Laden Sie das Skript Async Ich sehe keinen Grund, mit ID
OBender
17

Ich habs. Eine Art Hack, aber es funktioniert ziemlich gut:

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];

Ich übergebe die Parameter im Skript-Tag als Klassen:

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

Dieser Artikel hat sehr geholfen.

Tomer Lichtash
quelle
1
Der Artikel ist großartig!
Bartek Skwira
14
Klassen sollten verwendet werden, um Elemente so zu gestalten, dass keine Parameter übergeben werden.
Kspacja
5
@kspacja Ja, und HTML sollte nur Inhalte ohne Styling enthalten, außer wir müssen unsere DIV-Tags für Float- und Spaltenlayouts genau bestellen, da CSS den Job nicht wirklich erledigen kann, und wir sind damit irgendwie einverstanden. Hack weg, sage ich. Sie können jedoch "Daten" -Attribute verwenden, wenn Sie Konflikte vermeiden möchten oder wenn Sie der Typ sind, der den Schlaf darüber verliert.
Jason C
13

Eine andere Möglichkeit ist die Verwendung von Meta-Tags. Alle Daten, die an Ihr JavaScript übergeben werden sollen, können wie folgt zugewiesen werden:

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

Die Daten können dann wie folgt aus den Meta-Tags abgerufen werden (am besten in einem DOMContentLoaded-Ereignishandler):

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

Absolut kein Ärger mit jQuery oder Ähnlichem, keine Hacks und Workarounds erforderlich und funktioniert mit jeder HTML-Version, die Meta-Tags unterstützt ...

Robidu
quelle
Ich dachte, diese Methode sei bei weitem die einfachste von allen. Es funktioniert wie ein Zauber und gibt mir genau das, was ich brauche. Tolle Frage und fantastische Lösung!
Arios
10

JQuery bietet eine Möglichkeit, Parameter von HTML an Javascript zu übergeben:

Fügen Sie dies in die myhtml.htmlDatei ein:

<!-- 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>

Erstellen Sie im selben Verzeichnis eine subscript.jsDatei und legen Sie diese dort ab:

//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);

Ergebnis analysieren:

Beim Laden der Seite myhtml.html wird 'foobar.mp4' auf dem Bildschirm gedruckt. Die Variable video_filename wurde von HTML an Javascript übergeben. Javascript druckte es auf dem Bildschirm aus und es wurde als in das HTML im übergeordneten Element eingebettet angezeigt.

jsfiddle Beweis, dass das oben genannte funktioniert:

http://jsfiddle.net/xqr77dLt/

Eric Leschinski
quelle
7

Wenn Sie jquery verwenden, sollten Sie deren Datenmethode berücksichtigen .

Ich habe etwas Ähnliches verwendet, wie Sie es in Ihrer Antwort versucht haben, aber so:

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

Sie können auch eine Funktion erstellen, mit der Sie die GET-Parameter direkt abrufen können (dies wird häufig verwendet):

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');
rg88
quelle
4

Ich weiß, es ist ein sehr alter Thread, aber das könnte auch helfen, wenn jemand hierher kommt, sobald er nach einer Lösung sucht.

Grundsätzlich habe ich das document.currentScript verwendet, um das Element abzurufen, von dem mein Code ausgeführt wird, und ich filtere nach dem Namen der gesuchten Variablen. Ich habe es getan, um currentScript mit einer Methode namens "get" zu erweitern, damit wir den Wert in diesem Skript abrufen können, indem wir Folgendes verwenden:

document.currentScript.get('get_variable_name');

Auf diese Weise können wir Standardvariablen verwenden, um die Variablen abzurufen, ohne spezielle Attribute hinzuzufügen.

Dies ist der endgültige Code

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

Ich habe den IE vergessen :) Es könnte nicht einfacher sein ... Nun, ich habe nicht erwähnt, dass document.currentScript eine HTML5-Eigenschaft ist. Es wurde nicht für verschiedene Versionen von IE aufgenommen (ich habe bis IE11 getestet und es war noch nicht da). Aus Gründen der IE-Kompatibilität habe ich diesen Teil dem Code hinzugefügt:

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

Wir definieren hier einen alternativen Code für den IE, der das aktuelle Skriptobjekt zurückgibt, das in der Lösung zum Extrahieren von Parametern aus der src-Eigenschaft erforderlich ist. Dies ist nicht die perfekte Lösung für IE, da es einige Einschränkungen gibt. Wenn das Skript asynchron geladen wird. Neuere Browser sollten die Eigenschaft ".currentScript" enthalten.

Ich hoffe, es hilft.

Yared Rodriguez
quelle
3

Dank der jQuery besteht eine einfache HTML5-kompatible Lösung darin, ein zusätzliches HTML-Tag wie div zu erstellen, um die Daten zu speichern.

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);
    })
});

Live-Demo mit dem obigen Code: http://codepen.io/anon/pen/KzzNmQ?editors=1011#0

In der Live-Demo können Sie die Daten aus HTML5-Datenattributen * sehen, die verkettet und in das Protokoll gedruckt werden sollen.

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

gagallo7
quelle
1
Wir haben einige der anderen Lösungen durchlaufen, aber diese hat am besten funktioniert und ist auch ziemlich einfach zu implementieren. Vielen Dank!
Erik Kalkoken
Dies sollte die akzeptierte Lösung sein, da Sie das Skript anhand der ID referenzieren können und es sich um gültiges HTML5 handelt.
Tim S
2

Platzieren Sie die benötigten Werte an einer Stelle, an der das andere Skript sie abrufen kann, z. B. eine versteckte Eingabe, und ziehen Sie diese Werte dann aus ihrem Container, wenn Sie Ihr neues Skript initialisieren. Sie können sogar alle Ihre Parameter als JSON-Zeichenfolge in ein verstecktes Feld einfügen.

bwest
quelle
Danke für die Antwort. Die Parameter werden tatsächlich von den Benutzern eingegeben (die dieses Skript-Tag in ihren Code einbetten). Was dann?
Tomer Lichtash
Das einzige, woran ich denken kann, wenn Sie nicht die Kontrolle über beide Client / Server-Skripte haben, ist, die Benutzereingaben zu verwenden, um eine bestimmte .js-Datei mit ihren darin eingebetteten Eingaben zu generieren. Dies setzt voraus, dass Sie die Kontrolle haben ihre Beiträge zu sammeln und zu verarbeiten.
Bwest
Beantwortet die ursprüngliche Frage nicht: Wo sollen die Argumente abgelegt werden, wenn kein Formular für das Feld "Versteckt" vorhanden ist?
David Spector
2

Erstellen Sie ein Attribut, das eine Liste der Parameter enthält, wie folgt:

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

Rufen Sie dann in Ihrem JavaScript die Parameter als Array ab:

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
Mystisch
quelle
Was sind die Nachteile dieses Ansatzes?
Tronathan
@Tronathan Es gibt keine wirklichen Nachteile dieses Ansatzes und es gibt eine Polyfüllung für eine bessere Browserunterstützung. Der einzige Nachteil, den ich hier sehe, ist, dass Kommas nicht in Parameter eingefügt werden können, was normalerweise kein Problem darstellt. Sie können dies kompensieren, indem Sie das Trennzeichen in ein Zeichen ändern, das Sie nicht verwenden möchten.
Mystischer
2

Ich wollte Lösungen mit so viel Unterstützung wie möglich von alten Browsern. Ansonsten würde ich sagen , entweder die currentScript oder die Datenattribute würden Methode stilvollste sein.

Dies ist die einzige dieser Methoden, die hier noch nicht erwähnt wurde. Insbesondere wenn Sie aus irgendeinem Grund große Datenmengen haben, ist die beste Option möglicherweise:

lokaler Speicher

/* 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 bietet umfassende Unterstützung für moderne Browser und überraschend gute Unterstützung auch für ältere Browser, unter anderem für IE 8, Firefox 3.5 und Safari 4 [vor elf Jahren].

Wenn Sie nicht viele Daten haben, aber dennoch umfassende Browserunterstützung wünschen, ist die beste Option möglicherweise:

Meta-Tags [von Robidu]

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

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

Der Fehler dabei ist, dass sich der richtige Ort zum Platzieren von Meta-Tags [bis HTML 4] im Head-Tag befindet und Sie diese Daten möglicherweise nicht dort oben haben möchten. Um dies zu vermeiden oder Meta-Tags in den Text einzufügen, können Sie Folgendes verwenden:

Versteckter Absatz

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

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

Für noch mehr Browserunterstützung können Sie anstelle des versteckten Attributs eine CSS-Klasse verwenden:

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

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

Dies ist die Lösung für 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');
})
Greil Omatics
quelle