Jalankan kode JavaScript yang disimpan sebagai string

173

Bagaimana cara menjalankan JavaScript yang merupakan string?

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

Jawaban:

227

Dengan eval("my script here")fungsi.

Lennart Koopmann
sumber
11
Hati-hati ! Ini akan mengeksekusi kode karena itu berhati-hatilah dari mana / bagaimana Anda mendapatkan string ini. Harap diingat bahwa siapa pun dapat mencoba memasukkan kode jahat ke dalam string Anda.
Jon
@divinci Ini disebut "Cross Site Scripting". Lihat di sini: en.wikipedia.org/wiki/Cross-site_scripting .
Brendon Shaw
134

Anda dapat menjalankannya menggunakan fungsi. Contoh:

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

var F=new Function (theInstructions);

return(F());
Stefan
sumber
3
tetapi pada akhirnya - bukankah itu sama dengan menelepon var F=function(){eval(theInstructions);};?
Jörn Berkefeld
14
ya dan tidak: dengan kode eval juga akan dieksekusi, sementara dengan kode Function () tidak dieksekusi sampai F () (use case? periksa kesalahan sintaks tetapi tidak ingin mengeksekusi kode)
G3z
2
@stefan Ini cantik ...new Function("alert('Hello World');")()
Andrés Morales
Saya mencoba ini di dalam blok coba / tangkap, dan itu bekerja dengan sempurna. Sekarang saya dapat mengambil kode JavaScript apa pun yang diketik dalam blok teks, meneruskannya ke fungsi saya, dan menjalankannya. Blok tangkapan kemudian dapat menyisipkan pesan kesalahan dari mesin JavaScript ke elemen DOM dan menampilkan kesalahan dalam kode. Jika seseorang menginginkan fungsi yang saya tulis, maka setelah saya merapikannya, saya dapat mempostingnya di sini.
David Edwards
@ Davidvid Akan luar biasa jika Anda masih memilikinya dan mempostingnya.
Anoop
60

The evalfungsi akan mengevaluasi string yang dilewatkan untuk itu.

Tetapi penggunaan evalbisa berbahaya , jadi gunakan dengan hati-hati.

Sunting: annakata memiliki poin yang bagus - Tidak hanya eval berbahaya , itu lambat . Ini karena kode yang akan dievaluasi harus diuraikan di tempat, sehingga akan mengambil beberapa sumber daya komputasi.

coobird
sumber
34
super berbahaya DAN lambat - Anda harus berani, miring, menggarisbawahi, dan h1 bahwa
annakata
5
Saya ragu itu lebih lambat daripada memuat JavaScript di tempat lain di halaman, yang juga harus diuraikan. Jika lebih lambat, itu karena dilakukan dalam ruang lingkup yang berbeda, yang mungkin memaksa penciptaan sumber daya untuk ruang lingkup itu.
cgp
6
Jika Anda katakan eval()berbahaya. Apakah ada alternatif lain?
white_gecko
4
@coobird Saya tahu ini sedikit terlambat tapi mengapa itu berbahaya? Pengguna dapat dengan mudah menjalankan kode JavaScript di situs web Anda menggunakan konsol.
jkd
8
jika keamanan Anda bergantung pada javascript sisi klien, Anda telah mengacaukan banyak waktu dan tidak ada hubungannya dengan eval.
Matius
20

Gunakan eval ().

W3 Sekolah tur eval . Situs memiliki beberapa contoh eval yang dapat digunakan. Dokumentasi Mozilla membahas hal ini secara rinci.

Anda mungkin akan mendapatkan banyak peringatan tentang penggunaan ini dengan aman. JANGAN mengizinkan pengguna untuk menyuntikkan APA SAJA ke eval () karena ini adalah masalah keamanan yang sangat besar.

Anda juga ingin tahu bahwa eval () memiliki cakupan yang berbeda .

cgp
sumber
11
w3fools.com . W3C bahkan tidak memiliki sesuatu untuk dikatakan tentang eval. Jika Anda ingin menautkan ke sesuatu yang resmi, target ecma-international.org/ecma-262/5.1/#sec-15.1.2.1
Bergi
7
Saya tidak ingin "menautkan ke sesuatu yang resmi, saya ingin menautkan ke sesuatu yang dapat dibaca - Melihat apa yang Anda tautkan , itu tidak memberikan penjelasan tentang bagaimana itu digunakan, tidak ada contoh, tidak ada cara untuk mengotak-atik, dan menjelaskan metode secara terpisah Untuk seorang pemula, ini adalah tautan yang benar-benar tidak tepat. Hei, Anda tidak akan menjadi @bjorninge, kan?
cgp
1
Spesifikasi ini menjelaskan evallebih baik kepada saya daripada artikel W3Schools. Sesuatu yang dapat dibaca dengan penjelasan dan contoh yang bagus adalah developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . Dan tidak, saya tidak bjorninge
Bergi
Saya akan setuju bahwa ini bukan dokumentasi, dan saya akan setuju bahwa halaman mozilla adalah gambaran keseluruhan yang lebih baik. Sedikit tweak jawaban saya berdasarkan umpan balik
cgp
1
Mengenai tautan ecma-international.org, saya akan menggambarkannya sebagai dapat dibaca dan dihargai oleh semua orang dengan lebih dari 15 menit pengalaman dengan JS. Itu sangat bagus.
i336_
16

Coba ini:

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

Secara pribadi, saya tidak mengujinya tetapi tampaknya berhasil.

yanko
sumber
1
Anda lupa lolos penutupan> dalam skrip: var script = "<script type = \" text / javascript \ "> konten </ script \>";
rlib
1
Mengapa Anda harus keluar dari penutupan>?
Jools
11

Sedikit seperti yang dikatakan @Hossein Hajizadeh alerady, meskipun secara lebih rinci:

Ada alternatif untuk eval().

Fungsi setTimeout()ini dirancang untuk mengeksekusi sesuatu setelah interval milidetik, dan kode yang akan dieksekusi kebetulan diformat sebagai string.

Ini akan bekerja seperti ini:

ExecuteJavascriptString(); //Just for running it

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

1 berarti akan menunggu 1 milidetik sebelum menjalankan string.

Ini mungkin bukan cara yang paling benar untuk melakukannya, tetapi ini berhasil.

Anton Juul-Naber
sumber
Mengapa membuang satu milidetik ketika Anda dapat melewati 0 (nol) setTimeout? Perhatikan bahwa dalam hal apa pun itu akan membuat eksekusi tidak sinkron. Ini berarti bahwa semua kode yang mengikuti setTimeoutpanggilan akan dipanggil sebelum kode dilewatkan ke setTimeout(bahkan jika dipanggil dengan 0 (nol)).
Jox
🤷‍♀️ hanya berpikir itu lebih baik menjelaskan bagaimana setTimeout bekerja
Anton Juul-Naber
8
new Function('alert("Hello")')();

Saya pikir ini adalah cara terbaik.

MyMeMo
sumber
7

Gunakan eval seperti di bawah ini. Eval harus digunakan dengan hati-hati, pencarian sederhana tentang " eval is evil " harus memberikan beberapa petunjuk.

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    eval(s);
}
xk0der
sumber
2
Tip bagus untuk itu pencarian sederhana tentang "eval is evil" Terima kasih!
Taptronic
5

Memeriksa ini pada banyak skrip yang kompleks dan dikaburkan:

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
sumber
5

Jika Anda ingin menjalankan perintah tertentu (yaitu string) setelah waktu tertentu - cmd = kode Anda - InterVal = tunda untuk menjalankan

 function ExecStr(cmd, InterVal) {
    try {
        setTimeout(function () {
            var F = new Function(cmd);
            return (F());
        }, InterVal);
    } catch (e) { }
}
//sample
ExecStr("alert(20)",500);
Hossein Hajizadeh
sumber
@SteelBrain menambahkan sampel yang dijalankan oleh ExecStr ("alert (20)", 500);
Hossein Hajizadeh
1
Mengapa Valdi InterValdikapitalisasi?
Program Redwolf
4

Untuk pengguna yang menggunakan simpul dan yang peduli dengan implikasi konteks eval()tawaran nodejs vm. Ini menciptakan mesin virtual V8 yang dapat mem-sandbox eksekusi kode Anda dalam konteks terpisah.

Mengambil langkah lebih jauh adalah vm2yang mengeras vmmemungkinkan vm untuk menjalankan kode yang tidak dipercaya.

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
sumber
2
Alih-alih mengatakan "eval is evil" dan tidak memberikan konteks atau solusi, ini justru mencoba untuk menyelesaikan masalah. +1 untuk Anda
Program Redwolf
3
eval(s);

Tapi ini bisa berbahaya jika Anda mengambil data dari pengguna, meskipun saya kira jika mereka membuat peramban mereka sendiri adalah masalah mereka.

UnkwnTech
sumber
1
persis. Eval berbahaya di sisi server. Pada klien ... tidak terlalu banyak. Pengguna cukup mengetikkan javascript: someevilcode ke alamat browser dan boom. Eval di sana.
Esben Skov Pedersen
@EsbenSkovPedersen Itu setidaknya dicegah dalam chrome, dan itu memerlukan tindakan pengguna, yang bertentangan dengan situs yang evalkode dari pengguna, yang misalnya dapat membiarkan pengguna mencuri akun pengguna lain tanpa mereka sadari hanya dengan memuat halaman.
1j01
1
@ 1j01 Agar adil komentar saya berumur lima tahun.
Esben Skov Pedersen
@EsbenSkovPedersen Itu benar :)
1j01
2

Tidak yakin apakah ini curang atau tidak:

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
sumber
2

Saya menjawab pertanyaan serupa dan mendapat ide lain bagaimana mencapai ini tanpa menggunakan eval():

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

Pada kode di atas Anda pada dasarnya membuat Blob, berisi skrip Anda, untuk membuat URL Obyek (representasi file atau objek Blob dalam memori browser). Karena Anda memiliki srcproperti pada <script>tag, skrip akan dieksekusi dengan cara yang sama seolah-olah itu diambil dari URL lain.

akrn
sumber
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
sumber
1

eval harus melakukannya.

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

Ingat juga, bahwa eval sangat kuat dan sangat tidak aman. Anda sebaiknya yakin bahwa skrip yang Anda jalankan aman dan tidak dapat diubah oleh pengguna.

PatrikAkerstrand
sumber
1
Di JS semuanya dapat diubah oleh pengguna cukup ketik "javascript: document.write (" Hello World ");" ke hampir semua bilah alamat browser.
UnkwnTech
1
Ya, tapi Anda dapat membuat lebih sulit bagi dia dengan tidak menggunakan variabel global, bersembunyi fungsi Anda di penutupan dll Juga, dengan menghindari eval seperti wabah =)
PatrikAkerstrand
0

Seseorang dapat menggunakan mathjs

Cuplikan dari tautan di atas:

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

scopeadalah benda apa pun. Jadi, jika Anda melewatkan lingkup global ke fungsi evalute, Anda mungkin dapat menjalankan alert () secara dinamis.

Juga mathjs adalah pilihan yang jauh lebih baik daripada eval () karena berjalan dalam kotak pasir.

Seorang pengguna dapat mencoba untuk menyuntikkan kode JavaScript berbahaya melalui parser ekspresi. Pengurai ekspresi mathjs menawarkan lingkungan berpasir untuk mengeksekusi ekspresi yang seharusnya membuat ini tidak mungkin. Meskipun mungkin ada kerentanan keamanan yang tidak diketahui, jadi penting untuk berhati-hati, terutama ketika memungkinkan eksekusi sisi server dari ekspresi sewenang-wenang.

Mathjs versi yang lebih baru tidak menggunakan eval () atau Function ().

Parser secara aktif mencegah akses ke JavaScripts internal eval dan Function baru yang merupakan penyebab utama serangan keamanan. Mathjs versi 4 dan yang lebih baru tidak menggunakan eval JavaScript di bawah tenda. Versi 3 dan yang lebih lama memang menggunakan eval untuk langkah kompilasi. Ini bukan masalah keamanan secara langsung tetapi menghasilkan permukaan serangan yang lebih besar.

sziraqui
sumber
0

Menggunakan eval dan membuat Function baru untuk mengeksekusi javascript hadir dengan banyak risiko keamanan.

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

Saya lebih suka metode ini untuk mengeksekusi Javascript yang saya terima sebagai string.

MapMyMind
sumber