Виконати код JavaScript, збережений як рядок


173

Як виконати JavaScript, який є рядком?

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

Відповіді:


227

З eval("my script here")функцією.


11
Будь обережний ! Це виконує код, тому будьте обережні, де / як ви отримали цей рядок. Майте на увазі, що хтось може спробувати вставити шкідливий код у ваш рядок.
Джон

@divinci Це називається "Перехресний сценарій". Дивіться тут: en.wikipedia.org/wiki/Cross-site_scripting .
Брендон Шоу

134

Ви можете виконати його за допомогою функції. Приклад:

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

var F=new Function (theInstructions);

return(F());

3
але врешті-решт - це не те саме, що дзвонити var F=function(){eval(theInstructions);};?
Йорн Беркефельд

14
так і ні: з кодом eval також буде виконуватися, в той час як з функцією () функція () код не виконується до F () (використовуйте випадок? Перевірте наявність синтаксичної помилки, але не хочете виконувати код)
G3z

2
@stefan It beatifull ...new Function("alert('Hello World');")()
Андрес Моралес

Я спробував це всередині блоку "пробувати / ловити", і він відмінно працює. Тепер я можу взяти будь-який код JavaScript, введений у текстовий блок, передати його своїй функції та виконати. Потім блок ловлі може вставляти повідомлення про помилки з двигуна JavaScript в елемент DOM і відображати будь-які помилки в коді. Якщо хтось хоче функцію, яку я написав, після того, як я її прибрав, я можу розмістити її тут.
Девід Едвардс

@DavidEdwards Було б приголомшливо, якщо у вас все ще є і опублікуйте його.
Anoop

60

evalфункція буде оцінювати рядок , яка передається йому.

Але використання evalможе бути небезпечним , тому використовуйте обережно.

Редагувати: Аннаката має хороший момент - Не тільки eval небезпечно , але й повільно . Це тому, що код, який слід оцінювати, повинен бути проаналізований на місці, щоб зайняти деякі обчислювальні ресурси.


34
супер небезпечно І повільно - вам слід сміливим, курсивом, підкресленням і h1 що
annakata

5
Я сумніваюся, що це може бути повільніше, ніж завантажувати JavaScript де-небудь ще на сторінці, що також потрібно проаналізувати. Якщо це повільніше, то це тому, що це робиться в іншому обсязі, що може змусити створити ресурси для цього обсягу.
cgp

6
Якщо ви скажете, eval()це небезпечно. Чи є альтернатива?
white_gecko

4
@coobird Я знаю, це трохи пізно, але чому це небезпечно? Користувач може легко запустити код JavaScript на вашому веб-сайті за допомогою консолі.
jkd

7
якщо ваша безпека взагалі залежить від JavaScript на стороні клієнта, ви накрутили великий час і це не має нічого спільного з eval.
Метью

20

Використовуйте eval ().

Екскурсія по школах W3 . На сайті є кілька корисних прикладів eval.Документація Mozilla детально висвітлює це питання.

Ймовірно, ви отримаєте багато попереджень про безпечне використання. НЕ дозволяйте користувачам вводити будь-що в eval () оскільки це величезна проблема безпеки.

Ви також хочете знати, що eval () має іншу сферу застосування .


11
w3fools.com . W3C навіть не має нічого сказати про eval. Якщо ви хочете , щоб посилання на що - то чиновник, цільової ecma-international.org/ecma-262/5.1/#sec-15.1.2.1
Берги

7
Я не хотів "посилатися на що-небудь офіційне, я хотів пов’язати щось читабельне - дивлячись на те, що ви пов’язали, воно не дає пояснень, як це використовується, немає прикладів, немає способу повозитися, і описує метод ізольовано Для початківців це абсолютно невідповідне посилання. Ей, вам не трапилось би бути @bjorninge, чи не так?
cgp

1
Характеристика описується evalмені краще, ніж ця стаття W3Schools. Щось читабельне з хорошим поясненням та прикладами буде developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . І немає, я не bjorninge
Берги

Я погоджуся, що це не документація, і я погоджуюся, що сторінка Мозілла - це краще уявлення про неї. Трохи підмінив мою відповідь на основі відгуків
cgp

1
Щодо цього посилання ecma-international.org, я би назвав його читабельним і помітним всім, хто має більше 15 хвилин досвіду роботи з JS. Це дуже приємно.
i336_

16

Спробуйте це:

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

Особисто я цього не перевіряв, але, здається, працює.


1
Ви забули уникнути закриття> у скрипті: var script = "<script type = \" text / javascript \ "> content </ script \>";
rlib

1
Чому потрібно уникати закриття>?
Jools

11

Трохи схоже на те, що сказав @Hossein Hajizadeh alerady, хоча більш докладно:

Є альтернатива eval().

Функція setTimeout() призначена для виконання чого-небудь через інтервал мілісекунд, і код, який буде виконуватися саме так, буває форматований як рядок.

Це діятиме так:

ExecuteJavascriptString(); //Just for running it

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

1 означає, що він зачекає 1 мілісекунд, перш ніж виконати рядок.

Це може бути не самим правильним способом, але це працює.


Навіщо витрачати одну мілісекунд, коли можна передати 0 (нуль) setTimeout? Зауважте, що в будь-якому випадку воно зробить виконання асинхронним. Це означає, що весь код, який слідує за setTimeoutвикликом, буде викликаний до передачі коду setTimeout(навіть якщо він викликається з 0 (нуль)).
jox

🤷‍♀️ просто подумав, що краще пояснити, як працює setTimeout
Антон Юль-Набер

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

Я думаю, що це найкращий спосіб.


7

Використовуйте eval, як показано нижче. Eval слід застосовувати обережно, простий пошук про " eval - зло " повинен кинути деякі покажчики.

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

2
Хороша порада про те, що простий пошук про "eval - зло" Дякую!
Taptronic

5

Перевірив це на багатьох складних та заплутаних сценаріях:

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

Якщо ви хочете виконати певну команду (тобто рядок) через певний час - cmd = ваш код - InterVal = затримка для запуску

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

@SteelBrain додати зразок, запущений ExecStr ("сигнал (20)", 500);
Hossein Hajizadeh

1
Чому Valз InterValвеликої літери?
Програми

4

Для користувачів, які використовують вузол і пов'язані з контекстними наслідками eval()пропозицій nodejs vm. Він створює віртуальну машину V8, яка може пісочницю виконувати ваш код в окремому контексті.

Зробивши крок далі, це vm2твердіє, vmдозволяючи vm запускати ненадійний код.

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
Замість того, щоб сказати "eval є злом" і не даючи жодного контексту чи рішення, це насправді намагається вирішити проблему. +1 для вас
програми

3
eval(s);

Але це може бути небезпечно, якщо ви берете дані у користувачів, хоча я гадаю, якщо вони збивають власний веб-переглядач, це їхня проблема.


1
точно. Eval небезпечний на стороні сервера. Про клієнта ... не так вже й багато. Користувач міг просто ввести javascript: someevilcode в адресу браузера та бум. Овал прямо там.
Есбен Сков Педерсен

@EsbenSkovPedersen Цьому заважають хромувати принаймні, і для цього потрібні дії користувача, на відміну від сайту, який має evalкод у користувачів, який, наприклад, може дозволити користувачам красти акаунти інших користувачів, не знаючи, просто завантажуючи сторінку.
1j01

1
@ 1j01 Чесно кажучи, моєму коментарю п’ять років.
Есбен Сков Педерсен

@EsbenSkovPedersen Це правда :)
1j01

2

Не впевнений, чи це обман чи ні:

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

Я відповідав на подібне запитання і отримав ще одне уявлення, як цього досягти без використання eval():

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

У наведеному вище коді ви в основному створюєте Blob, що містить ваш скрипт, для створення URL-адреси об'єкта (представлення файлу або об'єкта Blob у пам'яті браузера). Оскільки у вас є srcвластивість <script>тегу, сценарій буде виконаний так само, як якщо б він був завантажений з будь-якої іншої 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);

Пам'ятайте, що цей евал дуже потужний і досить небезпечний. Вам краще бути впевненим, що виконаний вами сценарій є безпечним та незмінним для користувачів.


1
У JS все може бути змінено користувачем, просто введіть "javascript: document.write (" Hello World ");" майже в будь-який адресний рядок браузера.
UnkwnTech

1
Так, але ви можете ускладнити його, не використовуючи глобальних змінних, приховуючи свої функції в закриттях тощо. Також, уникаючи eval, як чума =)
PatrikAkerstrand

0

Можна використовувати математику

Фрагмент зверху за посиланням:

// 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- будь-який об’єкт. Отже, якщо ви передасте глобальну область дії функції оцінки, можливо, ви зможете виконати попередження () динамічно.

Також mathjs набагато кращий варіант, ніж eval (), оскільки він працює в пісочниці.

Користувач може спробувати ввести шкідливий код JavaScript через аналізатор виразів. Аналізатор виразів mathjs пропонує середовище з пісочницею для виконання виразів, які повинні зробити це неможливим. Незважаючи на те, що існують невідомі вразливості безпеки, тому важливо бути обережними, особливо якщо дозволяти сервер виконувати довільні вирази.

Новіші версії mathjs не використовують eval () або Function ().

Аналізатор активно запобігає доступу до внутрішнього eval JavaScripts та нової функції, які є основною причиною атак безпеки. Mathjs версії 4 і новіших не використовує eval JavaScript під кришкою. Версія 3 та старші використовували eval для кроку компіляції. Це не є безпосередньо проблемою безпеки, але призводить до збільшення можливої ​​поверхні атаки.


0

Використання як eval, так і створення нової функції для виконання javascript надає безліч ризиків для безпеки.

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

Я вважаю за краще цей метод виконувати Javascript, який я отримую як рядок.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.