Esegue il codice JavaScript archiviato come stringa


173

Come eseguo JavaScript che è una stringa?

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

Risposte:



134

Puoi eseguirlo usando una funzione. Esempio:

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

var F=new Function (theInstructions);

return(F());

3
ma alla fine non è lo stesso di chiamare var F=function(){eval(theInstructions);};?
Jörn Berkefeld,

14
sì e no: con il codice eval verrebbe anche eseguito, mentre con il codice Function () non verrà eseguito fino a F () (caso d'uso? controlla l'errore di sintassi ma non vuoi eseguire il codice)
G3z

2
@stefan È bello ...new Function("alert('Hello World');")()
Andrés Morales,

L'ho provato all'interno di un blocco try / catch e funziona perfettamente. Ora posso prendere qualsiasi codice JavaScript digitato in un blocco di testo, passarlo alla mia funzione ed eseguirlo. Il blocco catch può quindi inserire messaggi di errore dal motore JavaScript in un elemento DOM e visualizzare eventuali errori nel codice. Se qualcuno vuole la funzione che ho scritto, una volta che l'ho riordinata, posso pubblicarla qui.
David Edwards,

@DavidEdwards Sarebbe fantastico se lo hai ancora e pubblicalo.
Anoop,

60

La evalfunzione valuterà una stringa che le viene passata.

Ma l'uso di evalpuò essere pericoloso , quindi usalo con cautela.

Modifica: annakata ha un buon punto - Non solo è eval pericoloso , è lento . Questo perché il codice da valutare deve essere analizzato sul posto, in modo da richiedere alcune risorse di elaborazione.


34
super pericoloso E lento - dovresti grassetto, corsivo, sottolineato e h1 che
annakata

5
Sono dubbioso che sia più lento del caricamento di JavaScript in qualsiasi altra parte della pagina, che deve essere analizzato anche. Se è più lento, è perché è fatto in un ambito diverso, il che potrebbe costringere alla creazione di risorse per quell'ambito.
CG

6
Se dici che eval()è pericoloso. C'è qualche alternativa?
white_gecko

4
@coobird So che è un po 'tardi, ma perché è pericoloso? L'utente può facilmente eseguire il codice JavaScript sul tuo sito Web utilizzando la console.
jkd

8
se la tua sicurezza dipende dal javascript sul lato client, hai rovinato tutto e non ha nulla a che fare con eval.
Matteo,

20

Usa eval ().

W3 Schools tour of eval . Il sito ha alcuni esempi utilizzabili di eval.La documentazione di Mozilla tratta questo in dettaglio.

Probabilmente riceverai molti avvisi sull'utilizzo sicuro di questo. NON consentire agli utenti di iniettare NIENTE in eval () poiché si tratta di un enorme problema di sicurezza.

Ti consigliamo anche di sapere che eval () ha un ambito diverso .


11
w3fools.com . Il W3C non ha nemmeno niente da dire su eval. Se vuoi collegarti a qualcosa di ufficiale,
Bergi

7
Non volevo "collegarmi a qualcosa di ufficiale, volevo collegarmi a qualcosa di leggibile - Guardando ciò che hai collegato, non dà alcuna spiegazione di come viene utilizzato, nessun esempio, nessun modo di armeggiare e descrive il metodo in modo isolato Per un principiante, è un collegamento completamente inappropriato Ehi, non ti capita di essere @bjorninge, vero?
CG

1
Le specifiche evalmi descrivono meglio di quell'articolo di W3Schools. Qualcosa di leggibile con una buona spiegazione ed esempi sarebbe developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . E no, non sono bjorninge
Bergi il

Concordo sul fatto che non si tratta di documentazione e concordo sul fatto che la pagina di mozilla ne sia un quadro generale migliore. Ho leggermente modificato la mia risposta in base al feedback
CG

1
Per quanto riguarda quel link ecma-international.org, lo descriverei come leggibile e apprezzabile da chiunque abbia più di 15 minuti di esperienza con JS. È molto carino.
i336_

16

Prova questo:

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

Personalmente, non l'ho provato ma sembra funzionare.


1
Hai dimenticato di uscire di chiusura> nello script: var script = "<tipo di script = \" testo / javascript \ "> contenuto </ script \>";
rlib

1
Perché è necessario sfuggire alla chiusura>?
Jools

11

Un po 'come quello di @Hossein Hajizadeh detto alerady, anche se in modo più dettagliato:

C'è un'alternativa a eval() .

La funzione setTimeout() è progettata per eseguire qualcosa dopo un intervallo di millisecondi e il codice da eseguire in questo modo sembra essere formattato come una stringa.

Funzionerebbe così:

ExecuteJavascriptString(); //Just for running it

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

1 significa che attenderà 1 millisecondo prima di eseguire la stringa.

Potrebbe non essere il modo più corretto per farlo, ma funziona.


Perché perdere un millisecondo quando è possibile passare da 0 (zero) a setTimeout? Si noti che in ogni caso renderà l'esecuzione asincrona. Significa che tutto il codice che segue la setTimeoutchiamata verrà invocato prima che il codice venga passato setTimeout(anche se chiamato con 0 (zero)).
jox,

🤷‍♀️ ho pensato che spiegasse meglio come funziona setTimeout
Anton Juul-Naber l'

8
new Function('alert("Hello")')();

Penso che questo sia il modo migliore.


7

Usa eval come di seguito. Eval dovrebbe essere usato con cautela, una semplice ricerca su " eval is evil " dovrebbe dare alcuni suggerimenti.

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    eval(s);
}

2
Un buon consiglio su ciò che una semplice ricerca su "eval is evil" Grazie!
Taptronic,

5

Controllato questo su molti script complessi e offuscati:

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

5

Se si desidera eseguire un comando specifico (ovvero stringa) dopo un tempo specifico - cmd = il codice - InterVal = ritardo per l'esecuzione

 function ExecStr(cmd, InterVal) {
    try {
        setTimeout(function () {
            var F = new Function(cmd);
            return (F());
        }, InterVal);
    } catch (e) { }
}
//sample
ExecStr("alert(20)",500);

@SteelBrain aggiunge un esempio eseguito da ExecStr ("alert (20)", 500);
Hossein Hajizadeh,

1
Perché è Valin InterValmaiuscolo?
Programmi Redwolf,

4

Per gli utenti che utilizzano il nodo e che si occupano delle implicazioni di contesto delle eval()offerte nodejs vm. Crea una macchina virtuale V8 in grado di eseguire il sandbox dell'esecuzione del codice in un contesto separato.

Fare un ulteriore passo avanti è quello vm2che indurisce vmconsentendo a vm di eseguire codice non attendibile.

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.

2
Piuttosto che dire "eval is evil" e non dare alcun contesto o soluzione, questo in realtà cerca di risolvere il problema. +1 per te
Programmi Redwolf

3
eval(s);

Ma questo può essere pericoloso se stai prendendo i dati dagli utenti, anche se suppongo che il loro problema sia l'arresto anomalo del proprio browser.


1
Esattamente. Eval è pericoloso sul lato server. Sul client ... non così tanto. L'utente potrebbe semplicemente digitare javascript: someevilcode nell'indirizzo del browser e boom. Eval proprio lì.
Esben Skov Pedersen,

@EsbenSkovPedersen Questo è almeno impedito in Chrome e richiede l'intervento dell'utente, al contrario di un sito che evalè codice dagli utenti, che potrebbe ad esempio consentire agli utenti di rubare gli account di altri utenti senza che lo sappiano semplicemente caricando la pagina.
1j01

1
@ 1j01 Ad essere sinceri, il mio commento ha cinque anni.
Esben Skov Pedersen,

@EsbenSkovPedersen È vero :)
1j01

2

Non sono sicuro se questo è barare o no:

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


2

Stavo rispondendo a una domanda simile e ho avuto ancora un'altra idea su come raggiungere questo obiettivo senza usare eval():

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

Nel codice sopra puoi fondamentalmente creare BLOB, contenente il tuo script, al fine di creare l'URL oggetto (rappresentazione di oggetto File o BLOB nella memoria del browser). Poiché hai la srcproprietà sul <script>tag, lo script verrà eseguito come se fosse caricato da qualsiasi altro URL.


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!');");


0
eval(s);

Ricorda, però, che Eval è molto potente e abbastanza pericoloso. È meglio essere sicuri che lo script che si sta eseguendo sia sicuro e inamovibile dagli utenti.


1
In JS tutto può essere modificato dall'utente, basta digitare "javascript: document.write (" Hello World ");" nella barra degli indirizzi di quasi tutti i browser.
UnkwnTech,

1
Sì, ma puoi renderlo più difficile per lui non usando variabili globali, nascondendo le tue funzioni in chiusure ecc. Inoltre, evitando eval come la peste =)
PatrikAkerstrand

0

Si possono usare i mathjs

Snippet dal link sopra:

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

scopeè qualsiasi oggetto. Pertanto, se si passa l'ambito globale alla funzione di valutazione, potrebbe essere possibile eseguire alert () in modo dinamico.

Anche mathjs è un'opzione molto migliore di eval () perché funziona in un sandbox.

Un utente potrebbe provare a iniettare codice JavaScript dannoso tramite il parser di espressioni. Il parser di espressioni di mathjs offre un ambiente sandbox per eseguire espressioni che dovrebbero renderlo impossibile. È possibile tuttavia che vi siano vulnerabilità di sicurezza sconosciute, quindi è importante fare attenzione, soprattutto quando si consente l'esecuzione lato server di espressioni arbitrarie.

Le versioni più recenti di mathjs non usano eval () o Function ().

Il parser impedisce attivamente l'accesso all'eval interno di JavaScripts e alla nuova funzione che sono la causa principale degli attacchi alla sicurezza. Le versioni 4 e successive di Mathjs non utilizzano il codice JavaScript sotto il cofano. La versione 3 e precedenti hanno usato eval per la fase di compilazione. Questo non è direttamente un problema di sicurezza ma si traduce in una superficie di attacco possibile più ampia.


0

L'uso di eval e la creazione di una nuova funzione per eseguire javascript comporta molti rischi per la sicurezza.

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

Preferisco questo metodo per eseguire il Javascript che ricevo come stringa.

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.