Führen Sie als Zeichenfolge gespeicherten JavaScript-Code aus

173

Wie führe ich JavaScript aus, das eine Zeichenfolge ist?

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    // how do I get a browser to alert('hello')?
}
Divinci
quelle

Antworten:

227

Mit eval("my script here")Funktion.

Lennart Koopmann
quelle
11
Sei vorsichtig ! Dadurch wird der Code ausgeführt. Achten Sie daher darauf, woher / wie Sie diesen String erhalten haben. Beachten Sie, dass jeder versuchen kann, schädlichen Code in Ihre Zeichenfolge einzufügen.
Jon
@divinci Dies wird als "Cross Site Scripting" bezeichnet. Siehe hier: en.wikipedia.org/wiki/Cross-site_scripting .
Brendon Shaw
134

Sie können es mit einer Funktion ausführen. Beispiel:

var theInstructions = "alert('Hello World'); var x = 100";

var F=new Function (theInstructions);

return(F());
stefan
quelle
3
aber am Ende - ist das nicht dasselbe wie anrufen var F=function(){eval(theInstructions);};?
Jörn Berkefeld
14
ja und nein: mit eval wird auch Code ausgeführt, während mit Function () Code erst mit F () ausgeführt wird (Anwendungsfall? Auf Syntaxfehler prüfen, aber den Code nicht ausführen wollen)
G3z
2
@stefan Es ist schön ...new Function("alert('Hello World');")()
Andrés Morales
Ich habe dies in einem Try / Catch-Block versucht und es funktioniert perfekt. Ich kann jetzt jeden in einen Textblock eingegebenen JavaScript-Code nehmen, an meine Funktion übergeben und ausführen. Der catch-Block kann dann Fehlermeldungen von der JavaScript-Engine in ein DOM-Element einfügen und alle Fehler im Code anzeigen. Wenn jemand die Funktion haben möchte, die ich geschrieben habe, kann ich sie hier posten, sobald ich sie aufgeräumt habe.
David Edwards
@ DavidEdwards Wäre großartig, wenn du es noch hast und es postest.
Anoop
60

Die evalFunktion wertet eine Zeichenfolge aus, die an sie übergeben wird.

Die Verwendung von evalkann jedoch gefährlich sein . Verwenden Sie sie daher mit Vorsicht.

Bearbeiten: Annakata hat einen guten Punkt - Es ist nicht nur eval gefährlich , es ist langsam . Dies liegt daran, dass der auszuwertende Code vor Ort analysiert werden muss, damit einige Rechenressourcen benötigt werden.

Coobird
quelle
34
super gefährlich UND langsam - du solltest fett, kursiv, unterstrichen und h1 das
annakata
5
Ich bezweifle, dass es langsamer ist als das Laden von JavaScript an einer anderen Stelle auf der Seite, das ebenfalls analysiert werden muss. Wenn es langsamer ist, liegt es daran, dass es in einem anderen Bereich ausgeführt wird, wodurch möglicherweise Ressourcen für diesen Bereich erstellt werden.
CGP
6
Wenn Sie sagen, eval()ist gefährlich. Gibt es eine Alternative?
white_gecko
4
@coobird Ich weiß, das ist etwas spät, aber warum ist das gefährlich? Der Benutzer kann mithilfe der Konsole problemlos JavaScript-Code auf Ihrer Website ausführen.
JKD
7
Wenn Ihre Sicherheit überhaupt von clientseitigem Javascript abhängt, haben Sie große Probleme und es hat nichts mit der Bewertung zu tun.
Matthew
20

Verwenden Sie eval ().

W3 Schulrundgang durch eval . Die Site enthält einige brauchbare Beispiele für die Bewertung. Die Mozilla-Dokumentation behandelt dies ausführlich.

Sie werden wahrscheinlich viele Warnungen erhalten, wenn Sie dies sicher verwenden. Erlauben Sie Benutzern NICHT, ALLES in eval () zu injizieren, da dies ein großes Sicherheitsproblem darstellt.

Sie möchten auch wissen, dass eval () einen anderen Bereich hat .

cgp
quelle
11
w3fools.com . Das W3C hat nicht einmal etwas zu eval zu sagen. Wenn Sie auf etwas Offizielles verlinken
möchten
7
Ich wollte nicht "auf etwas Offizielles verlinken, ich wollte auf etwas Lesbares verlinken - Wenn ich mir anschaue, was Sie verlinkt haben, gibt es keine Erklärung für die Verwendung, keine Beispiele, keine Möglichkeit zum Basteln und beschreibt die Methode isoliert Für einen Anfänger ist es ein völlig unangemessener Link. Hey, du wärst doch nicht @bjorninge, oder?
cgp
1
Die Spezifikation beschreibt evalmich besser als dieser W3Schools-Artikel. Etwas Lesbares mit guten Erklärungen und Beispielen wäre developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . Und nein, ich bin nicht bjorninge
Bergi
Ich werde zustimmen, dass es keine Dokumentation ist, und ich werde zustimmen, dass Mozillas Seite ein besseres Gesamtbild davon ist. Meine Antwort wurde basierend auf dem Feedback
leicht angepasst
1
In Bezug auf diesen ecma-international.org-Link würde ich ihn für alle mit mehr als 15 Minuten Erfahrung mit JS als lesbar und wertvoll beschreiben. Es ist sehr nett.
i336_
16

Versuche dies:

  var script = "<script type='text/javascript'> content </script>";
  //using jquery next
  $('body').append(script);//incorporates and executes inmediatelly

Persönlich habe ich es nicht getestet, aber es scheint zu funktionieren.

yanko
quelle
1
Sie haben vergessen, dem Schließen> im Skript zu entkommen: var script = "<script type = \" text / javascript \ "> content </ script \>";
Rlib
1
Warum müssen Sie dem Schließen entkommen?
Jools
11

Ein bisschen wie das, was @Hossein Hajizadeh alerady gesagt hat, allerdings ausführlicher:

Es gibt eine Alternative zu eval().

Die Funktion setTimeout()ist so konzipiert, dass sie nach einem Intervall von Millisekunden etwas ausführt, und der auszuführende Code ist zufällig als Zeichenfolge formatiert.

Es würde so funktionieren:

ExecuteJavascriptString(); //Just for running it

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    setTimeout(s, 1);
}

1 bedeutet, dass 1 Millisekunde gewartet wird, bevor die Zeichenfolge ausgeführt wird.

Es ist vielleicht nicht der richtigste Weg, aber es funktioniert.

Anton Juul-Naber
quelle
Warum eine Millisekunde verschwenden, wenn Sie 0 (Null) an übergeben können setTimeout? Beachten Sie, dass die Ausführung in jedem Fall asynchron ist. Dies bedeutet, dass der gesamte Code, der auf den setTimeoutAufruf folgt, vor der Übergabe des Codes aufgerufen wird setTimeout(auch wenn er mit 0 (Null) aufgerufen wird).
Jox
Thought♀️ dachte nur, es würde besser erklären, wie setTimeout funktioniert
Anton Juul-Naber
8
new Function('alert("Hello")')();

Ich denke, das ist der beste Weg.

MyMeMo
quelle
7

Verwenden Sie eval wie unten. Eval sollte mit Vorsicht verwendet werden, eine einfache Suche nach " Eval ist böse " sollte einige Hinweise geben.

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    eval(s);
}
xk0der
quelle
2
Guter Tipp dazu eine einfache Suche nach "eval is evil" Danke!
Taptronic
5

Überprüfte dies bei vielen komplexen und verschleierten Skripten:

var js = "alert('Hello, World!');" // put your JS code here
var oScript = document.createElement("script");
var oScriptText = document.createTextNode(js);
oScript.appendChild(oScriptText);
document.body.appendChild(oScript);
rlib
quelle
5

Wenn Sie einen bestimmten Befehl (dh eine Zeichenfolge) nach einer bestimmten Zeit ausführen möchten - cmd = Ihr Code - InterVal = Verzögerung bei der Ausführung

 function ExecStr(cmd, InterVal) {
    try {
        setTimeout(function () {
            var F = new Function(cmd);
            return (F());
        }, InterVal);
    } catch (e) { }
}
//sample
ExecStr("alert(20)",500);
Hossein Hajizadeh
quelle
@SteelBrain fügt ein Beispiel hinzu, das von ExecStr ausgeführt wird ("alert (20)", 500);
Hossein Hajizadeh
1
Warum wird Valin InterValaktiviert?
Redwolf Programme
4

Für Benutzer, die Node verwenden und sich mit den Kontextauswirkungen von eval()NodeJS-Angeboten befassen vm. Es wird eine virtuelle V8-Maschine erstellt, die die Ausführung Ihres Codes in einem separaten Kontext sandboxen kann.

Wenn Sie noch einen Schritt weiter gehen, wird vm2die vmVM härter und kann nicht vertrauenswürdigen Code ausführen.

const vm = require('vm');

const x = 1;

const sandbox = { x: 2 };
vm.createContext(sandbox); // Contextify the sandbox.

const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the sandboxed environment.
// Initially, x has the value 2 because that is the value of sandbox.x.
vm.runInContext(code, sandbox);

console.log(sandbox.x); // 42
console.log(sandbox.y); // 17

console.log(x); // 1; y is not defined.
Eric Kigathi
quelle
2
Anstatt zu sagen, "Eval ist böse" und keinen Kontext oder keine Lösung anzugeben, versucht dies tatsächlich, das Problem zu lösen. +1 für Sie
Redwolf Programme
3
eval(s);

Dies kann jedoch gefährlich sein, wenn Sie Daten von Benutzern übernehmen, obwohl dies vermutlich das Problem ist, wenn sie ihren eigenen Browser zum Absturz bringen.

UnkwnTech
quelle
1
genau. Eval ist auf der Serverseite gefährlich. Auf dem Kunden ... nicht so sehr. Der Benutzer könnte einfach Javascript eingeben: Someevilcode in die Adresse des Browsers und Boom. Eval genau dort.
Esben Skov Pedersen
@EsbenSkovPedersen Dies wird zumindest in Chrome verhindert und erfordert Benutzeraktionen im Gegensatz zu einer Site, die evalCode von Benutzern enthält, mit der Benutzer beispielsweise die Konten anderer Benutzer stehlen können, ohne dass sie dies wissen, indem sie nur die Seite laden.
1j01
1
@ 1j01 Um fair zu sein, mein Kommentar ist fünf Jahre alt.
Esben Skov Pedersen
@EsbenSkovPedersen Das stimmt :)
1j01
2

Nicht sicher, ob dies betrügt oder nicht:

window.say = function(a) { alert(a); };

var a = "say('hello')";

var p = /^([^(]*)\('([^']*)'\).*$/;                 // ["say('hello')","say","hello"]

var fn = window[p.exec(a)[1]];                      // get function reference by name

if( typeof(fn) === "function") 
    fn.apply(null, [p.exec(a)[2]]);                 // call it with params
Zachary Scott
quelle
2

Ich beantwortete eine ähnliche Frage und bekam eine weitere Idee, wie ich dies erreichen kann, ohne Folgendes zu verwenden eval():

const source = "alert('test')";
const el = document.createElement("script");
el.src = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
document.head.appendChild(el);

Im obigen Code erstellen Sie im Wesentlichen einen Blob, der Ihr Skript enthält, um eine Objekt-URL (Darstellung des Datei- oder Blob-Objekts im Browserspeicher) zu erstellen. Da Sie eine srcEigenschaft für das <script>Tag haben, wird das Skript so ausgeführt, als ob es von einer anderen URL geladen worden wäre.

akrn
quelle
2
function executeScript(source) {
    var script = document.createElement("script");
    script.onload = script.onerror = function(){ this.remove(); };
    script.src = "data:text/plain;base64," + btoa(source);
    document.body.appendChild(script);
}

executeScript("alert('Hello, World!');");
Oleg
quelle
1

eval sollte es tun.

eval(s);
Vincent Ramdhanie
quelle
0
eval(s);

Denken Sie jedoch daran, dass die Bewertung sehr mächtig und ziemlich unsicher ist. Sie sollten besser sicher sein, dass das von Ihnen ausgeführte Skript für Benutzer sicher und unveränderlich ist.

PatrikAkerstrand
quelle
1
In JS kann alles vom Benutzer geändert werden. Geben Sie einfach "javascript: document.write (" Hello World ");" in fast die Adressleiste jedes Browsers.
UnkwnTech
1
Ja, aber Sie können es ihm schwerer machen, indem Sie keine globalen Variablen verwenden, Ihre Funktionen in Abschlüssen verstecken usw. Außerdem können Sie
Auswertungen
0

Man kann mathjs benutzen

Ausschnitt aus dem obigen Link:

// evaluate expressions
math.evaluate('sqrt(3^2 + 4^2)')        // 5
math.evaluate('sqrt(-4)')               // 2i
math.evaluate('2 inch to cm')           // 5.08 cm
math.evaluate('cos(45 deg)')            // 0.7071067811865476

// provide a scope
let scope = {
    a: 3,
    b: 4
}
math.evaluate('a * b', scope)           // 12
math.evaluate('c = 2.3 + 4.5', scope)   // 6.8
scope.c                                

scopeist irgendein Objekt. Wenn Sie also den globalen Bereich an die Auswertungsfunktion übergeben, können Sie alert () möglicherweise dynamisch ausführen.

Auch mathjs ist eine viel bessere Option als eval (), da es in einer Sandbox ausgeführt wird.

Ein Benutzer könnte versuchen, schädlichen JavaScript-Code über den Ausdrucksparser einzufügen. Der Ausdrucksparser von mathjs bietet eine Sandbox-Umgebung zum Ausführen von Ausdrücken, die dies unmöglich machen sollten. Es ist jedoch möglich, dass unbekannte Sicherheitslücken bestehen. Daher ist es wichtig, vorsichtig zu sein, insbesondere wenn die serverseitige Ausführung beliebiger Ausdrücke zulässig ist.

Neuere Versionen von mathjs verwenden weder eval () noch Function ().

Der Parser verhindert aktiv den Zugriff auf die interne Auswertung von JavaScripts und die neue Funktion, die die Hauptursache für Sicherheitsangriffe sind. Mathjs Version 4 und höher verwendet nicht die JavaScript-Bewertung unter der Haube. Version 3 und älter verwendeten eval für den Kompilierungsschritt. Dies ist kein direktes Sicherheitsproblem, führt jedoch zu einer größeren möglichen Angriffsfläche.

sziraqui
quelle
0

Die Verwendung von eval und das Erstellen einer neuen Funktion zum Ausführen von Javascript birgt viele Sicherheitsrisiken.

const script = document.createElement("script");
const stringJquery = '$("#button").on("click", function() {console.log("hit")})';
script.text = stringJquery;
document.body.appendChild(script);

Ich bevorzuge diese Methode, um das Javascript auszuführen, das ich als Zeichenfolge erhalte.

MapMyMind
quelle