Zum Inhalt springen

JavaScript eval()

JavaScript bietet Entwicklern leistungsstarke Möglichkeiten, Code dynamisch auszuführen. Unter diesen sticht die Funktion eval() hervor, da sie die Auswertung eines Strings als JavaScript-Code ermöglicht. In diesem umfassenden Leitfaden gehen wir auf die Feinheiten von eval() ein und liefern ausführliche Erklärungen, praktische Beispiele und professionelle Tipps, um Ihre JavaScript-Kenntnisse zu verbessern.

Die eval()-Funktion verstehen

Die Funktion eval() wertet ein Argument als JavaScript-Code aus oder führt es aus. Wenn das Argument ein Ausdruck ist, wertet eval() den Ausdruck aus. Wenn das Argument eine oder mehrere JavaScript-Anweisungen sind, führt eval() die Anweisungen aus.

Syntax


javascript
eval(string)

Parameter:

  • string: Ein String, der den auszuführenden JavaScript-Code darstellt.

Beispielverwendung

In diesem Beispiel werten wir mit eval() einen einfachen arithmetischen Ausdruck aus und zeigen das Ergebnis auf einer Webseite an.


Output appears here after Run.

Praktische Anwendungsfälle für eval()

Obwohl die Funktion eval() äußerst leistungsstark sein kann, wird ihre Verwendung aufgrund von Sicherheits- und Leistungsbedenken oft nicht empfohlen. Es gibt jedoch Szenarien, in denen eval() nützlich sein kann.

Dynamische Codeausführung

In Situationen, in denen Code dynamisch erzeugt und ausgeführt werden muss, kann eval() eine praktische Lösung sein. Zum Beispiel bei der Erstellung eines Taschenrechners, der Benutzereingaben als mathematischen Ausdruck auswertet:


html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Dynamic Calculator</title>
</head>
<body>
    <p>Add any arithmetic expression like 12 + 5 and hit 'Calculate' button!</p>
    <div>
        <input type="text" id="expression" placeholder="Enter expression" /> <!-- User input field -->
        <button onclick="evaluateExpression()">Calculate</button> <!-- Button to trigger calculation -->
    </div>
    <div id="calcResult"></div> <!-- Element to display result -->
    <script>
        function evaluateExpression() {
            const expression = document.getElementById('expression').value; // Get user input
            try {
                const result = eval(expression); // Evaluate the expression
                document.getElementById('calcResult').textContent = `Result: ${result}`; // Display the result
            } catch (e) {
                document.getElementById('calcResult').textContent = 'Invalid expression'; // Handle invalid input
            }
        }
    </script>
</body>
</html>

JSON mit eval() parsen

Vor der Einführung von JSON.parse() wurde eval() verwendet, um JSON-Strings zu parsen. Heute wird jedoch aufgrund von Sicherheitsbedenken empfohlen, JSON.parse() zu verwenden.


Output appears here after Run.

Wenn Sie eval() zum Parsen von JSON-Strings verwenden, ist es entscheidend sicherzustellen, dass der JSON-String als Objektausdruck und nicht als Blockanweisung interpretiert wird. Dazu wird der JSON-String vor dem Übergeben an eval() in Klammern gesetzt. Dadurch behandelt JavaScript den String als Objektausdruck und verhindert Syntaxfehler, die auftreten könnten, wenn der String als Blockanweisung interpretiert würde.

INFO

Verwenden Sie zum Parsen von JSON immer JSON.parse() statt eval(), um die Ausführung schädlicher Skripte zu vermeiden.

Sicherheits- und Leistungsaspekte

Die Verwendung von eval() kann erhebliche Sicherheitsrisiken und Leistungsprobleme mit sich bringen. Hier ist der Grund:

Sicherheitsrisiken

eval() kann beliebigen JavaScript-Code ausführen und ist dadurch anfällig für Injection-Angriffe. Ein Angreifer könnte potenziell schädlichen Code einschleusen und dadurch schwerwiegende Sicherheitsverletzungen verursachen.

Beispiel für ein Sicherheitsrisiko:

Stellen Sie sich eine Webanwendung vor, die Benutzereingaben entgegennimmt und sie mit eval() auswertet. Ohne ordnungsgemäße Validierung kann dies von einem Angreifer ausgenutzt werden, um schädlichen Code auszuführen.


html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>eval() Security Risk Example</title>
</head>
<body>
    <div>
     <p>Hit 'Run Code' button!</p>
        <input type="text" id="userInput" placeholder="Enter code" value="alert('Hacked!')" /> <!-- User input field -->
        <button onclick="evaluateUserInput()">Run Code</button> <!-- Button to run code -->
    </div>
    <div id="userInputResult"></div> <!-- Element to display result -->
    <script>
        function evaluateUserInput() {
            const input = document.getElementById('userInput').value; // Get user input
            try {
                const result = eval(input); // Evaluate the user input
                document.getElementById('userInputResult').textContent = `Result: ${result}`; // Display the result
            } catch (e) {
                document.getElementById('userInputResult').textContent = 'Error in evaluation'; // Handle evaluation error
            }
        }
    </script>
</body>
</html>

In diesem Beispiel führt eval() die Eingabe aus, wenn ein Benutzer etwas wie alert('Hacked!') eingibt, und verursacht dadurch eine Sicherheitsverletzung, indem ein Alert-Fenster angezeigt wird. Ein Angreifer könnte noch schädlicheren Code einschleusen und möglicherweise das gesamte System kompromittieren.

Leistungsprobleme

eval() führt Code im selben Gültigkeitsbereich aus, aus dem es aufgerufen wird, und behindert dadurch Optimierungen der JavaScript-Engine. Dies kann im Vergleich zu anderen Ansätzen zu geringerer Leistung führen.

Beispiel für ein Leistungsproblem:

Betrachten wir ein Szenario, in dem wir eine Reihe von Berechnungen mehrfach durchführen müssen. Die Verwendung von eval() für diese Aufgabe kann die Leistung erheblich beeinträchtigen.


html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Performance Issues with eval()</title>
</head>
<body>
    <div id="evalResult"></div>
    <div id="functionResult"></div>
    <script>
        // Using eval()
        const evalStartTime = performance.now();
        for (let i = 0; i < 100000; i++) {
            eval("3 * 4 + 5");
        }
        const evalEndTime = performance.now();
        const evalDuration = evalEndTime - evalStartTime;
        document.getElementById('evalResult').textContent = `Time taken with eval(): ${evalDuration} ms`;

        // Using Function constructor
        const func = new Function('return 3 * 4 + 5');
        const funcStartTime = performance.now();
        for (let i = 0; i < 100000; i++) {
            func();
        }
        const funcEndTime = performance.now();
        const funcDuration = funcEndTime - funcStartTime;
        document.getElementById('functionResult').textContent = `Time taken with Function constructor: ${funcDuration} ms`;
    </script>
</body>
</html>

In diesem Beispiel vergleichen wir die Leistung von eval() mit dem Konstruktor Function. Wir führen eine einfache arithmetische Operation (3 * 4 + 5) 100.000 Mal mit beiden Methoden aus und messen die jeweils benötigte Zeit.

  • Verwendung von eval(): Der Code innerhalb von eval() wird wiederholt ausgewertet, was langsamer ist, da bestimmte Optimierungen verhindert werden.
  • Verwendung des Function-Konstruktors: Der Function-Konstruktor erstellt eine Funktion, die dieselbe Operation ausführt, ist aber schneller, weil JavaScript-Engines die wiederholte Ausführung optimieren können.

Die auf der Webseite angezeigten Ergebnisse zeigen die für jede Methode benötigte Zeit und verdeutlichen, dass eval() aufgrund seiner Leistungsprobleme langsamer ist.

WARNING

Vermeiden Sie die Verwendung von eval(), es sei denn, es ist unbedingt notwendig. Erwägen Sie sicherere Alternativen wie den Function-Konstruktor oder JSON.parse().

Alternativen zu eval()

Für eine sicherere und effizientere Codeausführung sollten Sie die folgenden Alternativen in Betracht ziehen:

Verwendung des Function-Konstruktors

Der Function-Konstruktor erstellt ein neues Funktionsobjekt, ähnlich wie eval(), jedoch mit besserer Sicherheit und Leistung.


Output appears here after Run.

Verwendung von JSON.parse()

Zum Parsen von JSON-Strings ist JSON.parse() die bevorzugte Methode.


Output appears here after Run.

Best Practices für die Verwendung von eval()

Wenn Sie eval() unbedingt verwenden müssen, halten Sie sich an diese Best Practices, um Risiken zu minimieren:

1. Eingaben validieren

Stellen Sie sicher, dass die Eingabe an eval() streng validiert wird, um Code-Injection zu verhindern. Das bedeutet, dass nur sichere Zeichen und Ausdrücke zugelassen werden.

Beispiel:


Output appears here after Run.

In diesem Beispiel verwenden wir einen regulären Ausdruck, um die Benutzereingabe zu validieren. Es sind nur numerische Zeichen und grundlegende arithmetische Operatoren erlaubt. Wenn die Eingabe dem Muster entspricht, wird sie mit eval() ausgewertet. Andernfalls wird sie als ungültig abgelehnt.

2. Try-Catch verwenden

Umgeben Sie eval() mit einem Try-Catch-Block, um potenzielle Fehler elegant zu behandeln. Dadurch wird verhindert, dass die gesamte Anwendung abstürzt, wenn eval() auf einen Fehler stößt.

Beispiel:


Output appears here after Run.

Hier behandeln wir Syntaxfehler in der Benutzereingabe mit einem Try-Catch-Block. Wenn eval() einen Fehler wirft, wird dieser abgefangen und stattdessen eine Fehlermeldung protokolliert, anstatt die Anwendung zum Absturz zu bringen.

3. Gültigkeitsbereich einschränken

Minimieren Sie den Gültigkeitsbereich der für eval() zugänglichen Variablen, um potenzielle Schäden durch schädlichen Code zu begrenzen. Verwenden Sie einen sofort aufgerufenen Funktionsausdruck (IIFE), um einen lokalen Gültigkeitsbereich zu erstellen.

Beispiel:


Output appears here after Run.

In diesem Beispiel definieren wir innerhalb einer IIFE eine Funktion restrictedEval, um einen lokalen Gültigkeitsbereich zu erstellen. Diese Funktion wertet die Eingabe mit eval() aus, jedoch mit lokal definierten Variablen a und b. Die globalen Variablen a und b sind nicht zugänglich, was die Einschränkung des Gültigkeitsbereichs demonstriert.

Wenn Sie diese Best Practices befolgen, können Sie die mit der Verwendung von eval() verbundenen Risiken verringern und gleichzeitig bei Bedarf die dynamischen Codeausführungsfunktionen nutzen.

Fazit

Die Funktion eval() in JavaScript bietet ein leistungsstarkes Werkzeug für die dynamische Codeausführung, bringt jedoch erhebliche Risiken und Leistungseinbußen mit sich. Wenn Sie die richtigen Anwendungsfälle, Alternativen und Best Practices verstehen, können Sie ihre Vorteile nutzen und gleichzeitig potenzielle Probleme minimieren. Priorisieren Sie stets Sicherheit und Leistung, indem Sie Eingaben validieren und wann immer möglich sicherere Alternativen prüfen.

Practice

Was macht die eval()-Funktion in JavaScript?

Finden Sie das nützlich?

Dual-run-Vorschau — vergleichen Sie mit den Symfony-Routen live.